annotate src/share/vm/opto/library_call.cpp @ 14649:f6301b007a16

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 0f19095fd8c1
children ef7328717719
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10279
diff changeset
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1513
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1513
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1513
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
26 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
27 #include "classfile/vmSymbols.hpp"
2405
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 2385
diff changeset
28 #include "compiler/compileBroker.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
29 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
30 #include "oops/objArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
31 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
32 #include "opto/callGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
33 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
34 #include "opto/idealKit.hpp"
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
35 #include "opto/mathexactnode.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
36 #include "opto/mulnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
37 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
38 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
39 #include "opto/subnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
40 #include "prims/nativeLookup.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
41 #include "runtime/sharedRuntime.hpp"
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10279
diff changeset
42 #include "trace/traceMacros.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 class LibraryIntrinsic : public InlineCallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // Extend the set of intrinsics known to the runtime:
a61af66fc99e Initial load
duke
parents:
diff changeset
46 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
47 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
48 bool _is_virtual;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
49 bool _is_predicted;
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
50 bool _does_virtual_dispatch;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
51 vmIntrinsics::ID _intrinsic_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 public:
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
54 LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
55 : InlineCallGenerator(m),
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _is_virtual(is_virtual),
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
57 _is_predicted(is_predicted),
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
58 _does_virtual_dispatch(does_virtual_dispatch),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _intrinsic_id(id)
a61af66fc99e Initial load
duke
parents:
diff changeset
60 {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 virtual bool is_intrinsic() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 virtual bool is_virtual() const { return _is_virtual; }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
64 virtual bool is_predicted() const { return _is_predicted; }
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
65 virtual bool does_virtual_dispatch() const { return _does_virtual_dispatch; }
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12330
diff changeset
66 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
67 virtual Node* generate_predicate(JVMState* jvms);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
68 vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 };
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Local helper class for LibraryIntrinsic:
a61af66fc99e Initial load
duke
parents:
diff changeset
73 class LibraryCallKit : public GraphKit {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 private:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
75 LibraryIntrinsic* _intrinsic; // the library intrinsic being called
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
76 Node* _result; // the result node, if any
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
77 int _reexecute_sp; // the stack pointer when bytecode needs to be reexecuted
0
a61af66fc99e Initial load
duke
parents:
diff changeset
78
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
79 const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
80
0
a61af66fc99e Initial load
duke
parents:
diff changeset
81 public:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
82 LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
83 : GraphKit(jvms),
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
84 _intrinsic(intrinsic),
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
85 _result(NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
86 {
7200
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
87 // Check if this is a root compile. In that case we don't have a caller.
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
88 if (!jvms->has_method()) {
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
89 _reexecute_sp = sp();
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
90 } else {
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
91 // Find out how many arguments the interpreter needs when deoptimizing
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
92 // and save the stack pointer value so it can used by uncommon_trap.
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
93 // We find the argument count by looking at the declared signature.
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
94 bool ignored_will_link;
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
95 ciSignature* declared_signature = NULL;
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
96 ciMethod* ignored_callee = caller()->get_method_at_bci(bci(), ignored_will_link, &declared_signature);
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
97 const int nargs = declared_signature->arg_size_for_bc(caller()->java_code_at_bci(bci()));
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
98 _reexecute_sp = sp() + nargs; // "push" arguments back on stack
dd38cfd12c3a 8004319: test/gc/7168848/HumongousAlloc.java fails after 7172640
twisti
parents: 7194
diff changeset
99 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
102 virtual LibraryCallKit* is_LibraryCallKit() const { return (LibraryCallKit*)this; }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
103
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104 ciMethod* caller() const { return jvms()->method(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 int bci() const { return jvms()->bci(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
106 LibraryIntrinsic* intrinsic() const { return _intrinsic; }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 vmIntrinsics::ID intrinsic_id() const { return _intrinsic->intrinsic_id(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 ciMethod* callee() const { return _intrinsic->method(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 bool try_to_inline();
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
111 Node* try_to_predicate();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
112
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
113 void push_result() {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
114 // Push the result onto the stack.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
115 if (!stopped() && result() != NULL) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
116 BasicType bt = result()->bottom_type()->basic_type();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
117 push_node(bt, result());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
118 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
119 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
120
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
121 private:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
122 void fatal_unexpected_iid(vmIntrinsics::ID iid) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
123 fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
124 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
125
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
126 void set_result(Node* n) { assert(_result == NULL, "only set once"); _result = n; }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
127 void set_result(RegionNode* region, PhiNode* value);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
128 Node* result() { return _result; }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
129
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
130 virtual int reexecute_sp() { return _reexecute_sp; }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
131
0
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // Helper functions to inline natives
a61af66fc99e Initial load
duke
parents:
diff changeset
133 Node* generate_guard(Node* test, RegionNode* region, float true_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Node* generate_slow_guard(Node* test, RegionNode* region);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 Node* generate_fair_guard(Node* test, RegionNode* region);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 Node* generate_negative_guard(Node* index, RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // resulting CastII of index:
a61af66fc99e Initial load
duke
parents:
diff changeset
138 Node* *pos_index = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Node* generate_nonpositive_guard(Node* index, bool never_negative,
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // resulting CastII of index:
a61af66fc99e Initial load
duke
parents:
diff changeset
141 Node* *pos_index = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
142 Node* generate_limit_guard(Node* offset, Node* subseq_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
143 Node* array_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
144 RegionNode* region);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 Node* generate_current_thread(Node* &tls_output);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 address basictype2arraycopy(BasicType t, Node *src_offset, Node *dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
147 bool disjoint_bases, const char* &name, bool dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
148 Node* load_mirror_from_klass(Node* klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 Node* load_klass_from_mirror_common(Node* mirror, bool never_see_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
150 RegionNode* region, int null_path,
a61af66fc99e Initial load
duke
parents:
diff changeset
151 int offset);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
152 Node* load_klass_from_mirror(Node* mirror, bool never_see_null,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
153 RegionNode* region, int null_path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 int offset = java_lang_Class::klass_offset_in_bytes();
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
155 return load_klass_from_mirror_common(mirror, never_see_null,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
156 region, null_path,
a61af66fc99e Initial load
duke
parents:
diff changeset
157 offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 Node* load_array_klass_from_mirror(Node* mirror, bool never_see_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
160 RegionNode* region, int null_path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 int offset = java_lang_Class::array_klass_offset_in_bytes();
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
162 return load_klass_from_mirror_common(mirror, never_see_null,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163 region, null_path,
a61af66fc99e Initial load
duke
parents:
diff changeset
164 offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 Node* generate_access_flags_guard(Node* kls,
a61af66fc99e Initial load
duke
parents:
diff changeset
167 int modifier_mask, int modifier_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
168 RegionNode* region);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 Node* generate_interface_guard(Node* kls, RegionNode* region);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 Node* generate_array_guard(Node* kls, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 return generate_array_guard_common(kls, region, false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 Node* generate_non_array_guard(Node* kls, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 return generate_array_guard_common(kls, region, false, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 Node* generate_objArray_guard(Node* kls, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return generate_array_guard_common(kls, region, true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return generate_array_guard_common(kls, region, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 Node* generate_array_guard_common(Node* kls, RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
183 bool obj_array, bool not_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
184 Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
a61af66fc99e Initial load
duke
parents:
diff changeset
186 bool is_virtual = false, bool is_static = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return generate_method_call(method_id, false, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 return generate_method_call(method_id, true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
193 Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
194
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
195 Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
196 Node* make_string_method_node(int opcode, Node* str1, Node* str2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197 bool inline_string_compareTo();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 bool inline_string_indexOf();
a61af66fc99e Initial load
duke
parents:
diff changeset
199 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
200 bool inline_string_equals();
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
201 Node* round_double_node(Node* n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
202 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 bool inline_math_native(vmIntrinsics::ID id);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 bool inline_trig(vmIntrinsics::ID id);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
205 bool inline_math(vmIntrinsics::ID id);
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
206 void inline_math_mathExact(Node* math);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
207 bool inline_math_addExactI(bool is_increment);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
208 bool inline_math_addExactL(bool is_increment);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
209 bool inline_math_multiplyExactI();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
210 bool inline_math_multiplyExactL();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
211 bool inline_math_negateExactI();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
212 bool inline_math_negateExactL();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
213 bool inline_math_subtractExactI(bool is_decrement);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
214 bool inline_math_subtractExactL(bool is_decrement);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
215 bool inline_exp();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
216 bool inline_pow();
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
217 void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
218 bool inline_min_max(vmIntrinsics::ID id);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // This returns Type::AnyPtr, RawPtr, or OopPtr.
a61af66fc99e Initial load
duke
parents:
diff changeset
221 int classify_unsafe_addr(Node* &base, Node* &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 Node* make_unsafe_address(Node* base, Node* offset);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
223 // Helper for inline_unsafe_access.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
224 // Generates the guards that check whether the result of
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
225 // Unsafe.getObject should be recorded in an SATB log buffer.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
226 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
229 static bool klass_needs_init_guard(Node* kls);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
230 bool inline_unsafe_allocate();
a61af66fc99e Initial load
duke
parents:
diff changeset
231 bool inline_unsafe_copyMemory();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 bool inline_native_currentThread();
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
233 #ifdef TRACE_HAVE_INTRINSICS
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
234 bool inline_native_classID();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
235 bool inline_native_threadID();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
236 #endif
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
237 bool inline_native_time_funcs(address method, const char* funcName);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
238 bool inline_native_isInterrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 bool inline_native_Class_query(vmIntrinsics::ID id);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 bool inline_native_subtype_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 bool inline_native_newArray();
a61af66fc99e Initial load
duke
parents:
diff changeset
243 bool inline_native_getLength();
a61af66fc99e Initial load
duke
parents:
diff changeset
244 bool inline_array_copyOf(bool is_copyOfRange);
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
245 bool inline_array_equals();
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
246 void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 bool inline_native_clone(bool is_virtual);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 bool inline_native_Reflection_getCallerClass();
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Helper function for inlining native object hash method
a61af66fc99e Initial load
duke
parents:
diff changeset
250 bool inline_native_hashcode(bool is_virtual, bool is_static);
a61af66fc99e Initial load
duke
parents:
diff changeset
251 bool inline_native_getClass();
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Helper functions for inlining arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
254 bool inline_arraycopy();
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void generate_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
256 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
257 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
258 Node* dest, Node* dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
259 Node* copy_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
260 bool disjoint_bases = false,
a61af66fc99e Initial load
duke
parents:
diff changeset
261 bool length_never_negative = false,
a61af66fc99e Initial load
duke
parents:
diff changeset
262 RegionNode* slow_region = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 AllocateArrayNode* tightly_coupled_allocation(Node* ptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
264 RegionNode* slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void generate_clear_array(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
266 Node* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
267 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
268 Node* slice_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
269 Node* slice_len,
a61af66fc99e Initial load
duke
parents:
diff changeset
270 Node* slice_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 bool generate_block_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
272 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
273 AllocateNode* alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
274 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
275 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
276 Node* dest_size, bool dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
277 void generate_slow_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
278 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
279 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
280 Node* copy_length, bool dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
281 Node* generate_checkcast_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
282 Node* dest_elem_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
283 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
284 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
285 Node* copy_length, bool dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
286 Node* generate_generic_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
287 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
288 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
289 Node* copy_length, bool dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
290 void generate_unchecked_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
291 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
292 bool disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
293 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
294 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
295 Node* copy_length, bool dest_uninitialized);
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
296 typedef enum { LS_xadd, LS_xchg, LS_cmpxchg } LoadStoreKind;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
297 bool inline_unsafe_load_store(BasicType type, LoadStoreKind kind);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
298 bool inline_unsafe_ordered_store(BasicType type);
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
299 bool inline_unsafe_fence(vmIntrinsics::ID id);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300 bool inline_fp_conversions(vmIntrinsics::ID id);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
301 bool inline_number_methods(vmIntrinsics::ID id);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
302 bool inline_reference_get();
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
303 bool inline_aescrypt_Block(vmIntrinsics::ID id);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
304 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
305 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
306 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
14261
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
307 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
7637
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
308 bool inline_encodeISOArray();
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
309 bool inline_updateCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
310 bool inline_updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
311 bool inline_updateByteBufferCRC32();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
312 };
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 //---------------------------make_vm_intrinsic----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
316 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 vmIntrinsics::ID id = m->intrinsic_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
318 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 if (DisableIntrinsic[0] != '\0'
a61af66fc99e Initial load
duke
parents:
diff changeset
321 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // disabled by a user request on the command line:
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // example: -XX:DisableIntrinsic=_hashCode,_getClass
a61af66fc99e Initial load
duke
parents:
diff changeset
324 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 if (!m->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // do not attempt to inline unloaded methods
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // Only a few intrinsics implement a virtual dispatch.
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // They are expensive calls which are also frequently overridden.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 if (is_virtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 case vmIntrinsics::_hashCode:
a61af66fc99e Initial load
duke
parents:
diff changeset
337 case vmIntrinsics::_clone:
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // OK, Object.hashCode and Object.clone intrinsics come in both flavors
a61af66fc99e Initial load
duke
parents:
diff changeset
339 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
340 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
341 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // -XX:-InlineNatives disables nearly all intrinsics:
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if (!InlineNatives) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 case vmIntrinsics::_indexOf:
a61af66fc99e Initial load
duke
parents:
diff changeset
349 case vmIntrinsics::_compareTo:
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
350 case vmIntrinsics::_equals:
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
351 case vmIntrinsics::_equalsC:
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
352 case vmIntrinsics::_getAndAddInt:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
353 case vmIntrinsics::_getAndAddLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
354 case vmIntrinsics::_getAndSetInt:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
355 case vmIntrinsics::_getAndSetLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
356 case vmIntrinsics::_getAndSetObject:
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
357 case vmIntrinsics::_loadFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
358 case vmIntrinsics::_storeFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
359 case vmIntrinsics::_fullFence:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 break; // InlineNatives does not control String.compareTo
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
361 case vmIntrinsics::_Reference_get:
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
362 break; // InlineNatives does not control Reference.get
0
a61af66fc99e Initial load
duke
parents:
diff changeset
363 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
364 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
368 bool is_predicted = false;
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
369 bool does_virtual_dispatch = false;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
370
0
a61af66fc99e Initial load
duke
parents:
diff changeset
371 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 case vmIntrinsics::_compareTo:
a61af66fc99e Initial load
duke
parents:
diff changeset
373 if (!SpecialStringCompareTo) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
374 if (!Matcher::match_rule_supported(Op_StrComp)) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 case vmIntrinsics::_indexOf:
a61af66fc99e Initial load
duke
parents:
diff changeset
377 if (!SpecialStringIndexOf) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 break;
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
379 case vmIntrinsics::_equals:
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
380 if (!SpecialStringEquals) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
381 if (!Matcher::match_rule_supported(Op_StrEquals)) return NULL;
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
382 break;
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
383 case vmIntrinsics::_equalsC:
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
384 if (!SpecialArraysEquals) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
385 if (!Matcher::match_rule_supported(Op_AryEq)) return NULL;
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
386 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
387 case vmIntrinsics::_arraycopy:
a61af66fc99e Initial load
duke
parents:
diff changeset
388 if (!InlineArrayCopy) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
390 case vmIntrinsics::_copyMemory:
a61af66fc99e Initial load
duke
parents:
diff changeset
391 if (StubRoutines::unsafe_arraycopy() == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
392 if (!InlineArrayCopy) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 case vmIntrinsics::_hashCode:
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if (!InlineObjectHash) return NULL;
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
396 does_virtual_dispatch = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
397 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
398 case vmIntrinsics::_clone:
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
399 does_virtual_dispatch = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
400 case vmIntrinsics::_copyOf:
a61af66fc99e Initial load
duke
parents:
diff changeset
401 case vmIntrinsics::_copyOfRange:
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if (!InlineObjectCopy) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // These also use the arraycopy intrinsic mechanism:
a61af66fc99e Initial load
duke
parents:
diff changeset
404 if (!InlineArrayCopy) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 break;
7637
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
406 case vmIntrinsics::_encodeISOArray:
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
407 if (!SpecialEncodeISOArray) return NULL;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
408 if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return NULL;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
409 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
410 case vmIntrinsics::_checkIndex:
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // We do not intrinsify this. The optimizer does fine with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
412 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 case vmIntrinsics::_getCallerClass:
a61af66fc99e Initial load
duke
parents:
diff changeset
415 if (!UseNewReflection) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 if (!InlineReflectionGetCallerClass) return NULL;
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
417 if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
418 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
419
643
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 605
diff changeset
420 case vmIntrinsics::_bitCount_i:
5934
61b82be3b1ff 7152957: VM crashes with assert(false) failed: bad AD file
never
parents: 5927
diff changeset
421 if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL;
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
422 break;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
423
643
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 605
diff changeset
424 case vmIntrinsics::_bitCount_l:
5934
61b82be3b1ff 7152957: VM crashes with assert(false) failed: bad AD file
never
parents: 5927
diff changeset
425 if (!Matcher::match_rule_supported(Op_PopCountL)) return NULL;
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
426 break;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
427
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
428 case vmIntrinsics::_numberOfLeadingZeros_i:
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
429 if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
430 break;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
431
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
432 case vmIntrinsics::_numberOfLeadingZeros_l:
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
433 if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
434 break;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
435
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
436 case vmIntrinsics::_numberOfTrailingZeros_i:
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
437 if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
438 break;
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
439
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
440 case vmIntrinsics::_numberOfTrailingZeros_l:
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
441 if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL;
643
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 605
diff changeset
442 break;
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 605
diff changeset
443
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
444 case vmIntrinsics::_reverseBytes_c:
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
445 if (!Matcher::match_rule_supported(Op_ReverseBytesUS)) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
446 break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
447 case vmIntrinsics::_reverseBytes_s:
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
448 if (!Matcher::match_rule_supported(Op_ReverseBytesS)) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
449 break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
450 case vmIntrinsics::_reverseBytes_i:
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
451 if (!Matcher::match_rule_supported(Op_ReverseBytesI)) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
452 break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
453 case vmIntrinsics::_reverseBytes_l:
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
454 if (!Matcher::match_rule_supported(Op_ReverseBytesL)) return NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
455 break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
456
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
457 case vmIntrinsics::_Reference_get:
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
458 // Use the intrinsic version of Reference.get() so that the value in
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
459 // the referent field can be registered by the G1 pre-barrier code.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
460 // Also add memory barrier to prevent commoning reads from this field
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
461 // across safepoint since GC can change it value.
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
462 break;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
463
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
464 case vmIntrinsics::_compareAndSwapObject:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
465 #ifdef _LP64
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
466 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_CompareAndSwapP)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
467 #endif
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
468 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
469
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
470 case vmIntrinsics::_compareAndSwapLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
471 if (!Matcher::match_rule_supported(Op_CompareAndSwapL)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
472 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
473
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
474 case vmIntrinsics::_getAndAddInt:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
475 if (!Matcher::match_rule_supported(Op_GetAndAddI)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
476 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
477
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
478 case vmIntrinsics::_getAndAddLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
479 if (!Matcher::match_rule_supported(Op_GetAndAddL)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
480 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
481
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
482 case vmIntrinsics::_getAndSetInt:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
483 if (!Matcher::match_rule_supported(Op_GetAndSetI)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
484 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
485
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
486 case vmIntrinsics::_getAndSetLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
487 if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
488 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
489
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
490 case vmIntrinsics::_getAndSetObject:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
491 #ifdef _LP64
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
492 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
493 if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
494 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
495 #else
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
496 if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
497 break;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
498 #endif
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
499
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
500 case vmIntrinsics::_aescrypt_encryptBlock:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
501 case vmIntrinsics::_aescrypt_decryptBlock:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
502 if (!UseAESIntrinsics) return NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
503 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
504
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
505 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
506 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
507 if (!UseAESIntrinsics) return NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
508 // these two require the predicated logic
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
509 is_predicted = true;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
510 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
511
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
512 case vmIntrinsics::_updateCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
513 case vmIntrinsics::_updateBytesCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
514 case vmIntrinsics::_updateByteBufferCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
515 if (!UseCRC32Intrinsics) return NULL;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
516 break;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
517
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
518 case vmIntrinsics::_incrementExactI:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
519 case vmIntrinsics::_addExactI:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
520 if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
521 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
522 case vmIntrinsics::_incrementExactL:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
523 case vmIntrinsics::_addExactL:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
524 if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
525 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
526 case vmIntrinsics::_decrementExactI:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
527 case vmIntrinsics::_subtractExactI:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
528 if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
529 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
530 case vmIntrinsics::_decrementExactL:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
531 case vmIntrinsics::_subtractExactL:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
532 if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
533 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
534 case vmIntrinsics::_negateExactI:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
535 if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
536 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
537 case vmIntrinsics::_negateExactL:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
538 if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
539 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
540 case vmIntrinsics::_multiplyExactI:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
541 if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
542 break;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
543 case vmIntrinsics::_multiplyExactL:
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
544 if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
545 break;
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
546
0
a61af66fc99e Initial load
duke
parents:
diff changeset
547 default:
856
75596850f863 6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents: 851
diff changeset
548 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
75596850f863 6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents: 851
diff changeset
549 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
550 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // -XX:-InlineClassNatives disables natives from the Class class.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // The flag applies to all reflective calls, notably Array.newArray
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // (visible to Java programmers as Array.newInstance).
a61af66fc99e Initial load
duke
parents:
diff changeset
556 if (m->holder()->name() == ciSymbol::java_lang_Class() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
557 m->holder()->name() == ciSymbol::java_lang_reflect_Array()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if (!InlineClassNatives) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // -XX:-InlineThreadNatives disables natives from the Thread class.
a61af66fc99e Initial load
duke
parents:
diff changeset
562 if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if (!InlineThreadNatives) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
567 if (m->holder()->name() == ciSymbol::java_lang_Math() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
568 m->holder()->name() == ciSymbol::java_lang_Float() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
569 m->holder()->name() == ciSymbol::java_lang_Double()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 if (!InlineMathNatives) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (!InlineUnsafeOps) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577
12330
29bdcf12457c 8014447: Object.hashCode intrinsic breaks inline caches
shade
parents: 12323
diff changeset
578 return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 //----------------------register_library_intrinsics-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // Initialize this file's data structures, for each Compile instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
583 void Compile::register_library_intrinsics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // Nothing to do here.
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12330
diff changeset
587 JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
588 LibraryCallKit kit(jvms, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
589 Compile* C = kit.C;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 int nodes = C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
591 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
592 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
593 char buf[1000];
a61af66fc99e Initial load
duke
parents:
diff changeset
594 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
a61af66fc99e Initial load
duke
parents:
diff changeset
595 tty->print_cr("Intrinsic %s", str);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 }
a61af66fc99e Initial load
duke
parents:
diff changeset
597 #endif
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
598 ciMethod* callee = kit.callee();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
599 const int bci = kit.bci();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
600
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
601 // Try to inline the intrinsic.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
602 if (kit.try_to_inline()) {
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
603 if (C->print_intrinsics() || C->print_inlining()) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
604 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 if (C->log()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 C->log()->elem("intrinsic id='%s'%s nodes='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
609 vmIntrinsics::name_at(intrinsic_id()),
a61af66fc99e Initial load
duke
parents:
diff changeset
610 (is_virtual() ? " virtual='1'" : ""),
a61af66fc99e Initial load
duke
parents:
diff changeset
611 C->unique() - nodes);
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
613 // Push the result from the inlined method onto the stack.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
614 kit.push_result();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
615 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
618 // The intrinsic bailed out
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
619 if (C->print_intrinsics() || C->print_inlining()) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
620 if (jvms->has_method()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
621 // Not a root compile.
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4902
diff changeset
622 const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
623 C->print_inlining(callee, jvms->depth() - 1, bci, msg);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
624 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
625 // Root compile
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
626 tty->print("Did not generate intrinsic %s%s at bci:%d in",
856
75596850f863 6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents: 851
diff changeset
627 vmIntrinsics::name_at(intrinsic_id()),
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
628 (is_virtual() ? " (virtual)" : ""), bci);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
629 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
635 Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
636 LibraryCallKit kit(jvms, this);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
637 Compile* C = kit.C;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
638 int nodes = C->unique();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
639 #ifndef PRODUCT
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
640 assert(is_predicted(), "sanity");
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
641 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
642 char buf[1000];
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
643 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
644 tty->print_cr("Predicate for intrinsic %s", str);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
645 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
646 #endif
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
647 ciMethod* callee = kit.callee();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
648 const int bci = kit.bci();
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
649
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
650 Node* slow_ctl = kit.try_to_predicate();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
651 if (!kit.failing()) {
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
652 if (C->print_intrinsics() || C->print_inlining()) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
653 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
654 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
655 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
656 if (C->log()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
657 C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'",
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
658 vmIntrinsics::name_at(intrinsic_id()),
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
659 (is_virtual() ? " virtual='1'" : ""),
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
660 C->unique() - nodes);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
661 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
662 return slow_ctl; // Could be NULL if the check folds.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
663 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
664
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
665 // The intrinsic bailed out
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
666 if (C->print_intrinsics() || C->print_inlining()) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
667 if (jvms->has_method()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
668 // Not a root compile.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
669 const char* msg = "failed to generate predicate for intrinsic";
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
670 C->print_inlining(kit.callee(), jvms->depth() - 1, bci, msg);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
671 } else {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
672 // Root compile
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
673 C->print_inlining_stream()->print("Did not generate predicate for intrinsic %s%s at bci:%d in",
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
674 vmIntrinsics::name_at(intrinsic_id()),
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
675 (is_virtual() ? " (virtual)" : ""), bci);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
676 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
677 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
678 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
679 return NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
680 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
681
0
a61af66fc99e Initial load
duke
parents:
diff changeset
682 bool LibraryCallKit::try_to_inline() {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // Handle symbolic names for otherwise undistinguished boolean switches:
a61af66fc99e Initial load
duke
parents:
diff changeset
684 const bool is_store = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
685 const bool is_native_ptr = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
686 const bool is_static = true;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
687 const bool is_volatile = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
688
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
689 if (!jvms()->has_method()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
690 // Root JVMState has a null method.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
691 assert(map()->memory()->Opcode() == Op_Parm, "");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
692 // Insert the memory aliasing node
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
693 set_all_memory(reset_memory());
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
694 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
695 assert(merged_memory(), "");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
696
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
697
0
a61af66fc99e Initial load
duke
parents:
diff changeset
698 switch (intrinsic_id()) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
699 case vmIntrinsics::_hashCode: return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
700 case vmIntrinsics::_identityHashCode: return inline_native_hashcode(/*!virtual*/ false, is_static);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
701 case vmIntrinsics::_getClass: return inline_native_getClass();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 case vmIntrinsics::_dsin:
a61af66fc99e Initial load
duke
parents:
diff changeset
704 case vmIntrinsics::_dcos:
a61af66fc99e Initial load
duke
parents:
diff changeset
705 case vmIntrinsics::_dtan:
a61af66fc99e Initial load
duke
parents:
diff changeset
706 case vmIntrinsics::_dabs:
a61af66fc99e Initial load
duke
parents:
diff changeset
707 case vmIntrinsics::_datan2:
a61af66fc99e Initial load
duke
parents:
diff changeset
708 case vmIntrinsics::_dsqrt:
a61af66fc99e Initial load
duke
parents:
diff changeset
709 case vmIntrinsics::_dexp:
a61af66fc99e Initial load
duke
parents:
diff changeset
710 case vmIntrinsics::_dlog:
a61af66fc99e Initial load
duke
parents:
diff changeset
711 case vmIntrinsics::_dlog10:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
712 case vmIntrinsics::_dpow: return inline_math_native(intrinsic_id());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 case vmIntrinsics::_min:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
715 case vmIntrinsics::_max: return inline_min_max(intrinsic_id());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
716
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
717 case vmIntrinsics::_addExactI: return inline_math_addExactI(false /* add */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
718 case vmIntrinsics::_addExactL: return inline_math_addExactL(false /* add */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
719 case vmIntrinsics::_decrementExactI: return inline_math_subtractExactI(true /* decrement */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
720 case vmIntrinsics::_decrementExactL: return inline_math_subtractExactL(true /* decrement */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
721 case vmIntrinsics::_incrementExactI: return inline_math_addExactI(true /* increment */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
722 case vmIntrinsics::_incrementExactL: return inline_math_addExactL(true /* increment */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
723 case vmIntrinsics::_multiplyExactI: return inline_math_multiplyExactI();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
724 case vmIntrinsics::_multiplyExactL: return inline_math_multiplyExactL();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
725 case vmIntrinsics::_negateExactI: return inline_math_negateExactI();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
726 case vmIntrinsics::_negateExactL: return inline_math_negateExactL();
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
727 case vmIntrinsics::_subtractExactI: return inline_math_subtractExactI(false /* subtract */);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
728 case vmIntrinsics::_subtractExactL: return inline_math_subtractExactL(false /* subtract */);
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
729
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
730 case vmIntrinsics::_arraycopy: return inline_arraycopy();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
731
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
732 case vmIntrinsics::_compareTo: return inline_string_compareTo();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
733 case vmIntrinsics::_indexOf: return inline_string_indexOf();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
734 case vmIntrinsics::_equals: return inline_string_equals();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
735
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
736 case vmIntrinsics::_getObject: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
737 case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
738 case vmIntrinsics::_getByte: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
739 case vmIntrinsics::_getShort: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
740 case vmIntrinsics::_getChar: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
741 case vmIntrinsics::_getInt: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
742 case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
743 case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
744 case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
745
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
746 case vmIntrinsics::_putObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
747 case vmIntrinsics::_putBoolean: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
748 case vmIntrinsics::_putByte: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
749 case vmIntrinsics::_putShort: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
750 case vmIntrinsics::_putChar: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
751 case vmIntrinsics::_putInt: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
752 case vmIntrinsics::_putLong: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
753 case vmIntrinsics::_putFloat: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
754 case vmIntrinsics::_putDouble: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
755
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
756 case vmIntrinsics::_getByte_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_BYTE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
757 case vmIntrinsics::_getShort_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_SHORT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
758 case vmIntrinsics::_getChar_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_CHAR, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
759 case vmIntrinsics::_getInt_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_INT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
760 case vmIntrinsics::_getLong_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_LONG, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
761 case vmIntrinsics::_getFloat_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_FLOAT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
762 case vmIntrinsics::_getDouble_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_DOUBLE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
763 case vmIntrinsics::_getAddress_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_ADDRESS, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
764
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
765 case vmIntrinsics::_putByte_raw: return inline_unsafe_access( is_native_ptr, is_store, T_BYTE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
766 case vmIntrinsics::_putShort_raw: return inline_unsafe_access( is_native_ptr, is_store, T_SHORT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
767 case vmIntrinsics::_putChar_raw: return inline_unsafe_access( is_native_ptr, is_store, T_CHAR, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
768 case vmIntrinsics::_putInt_raw: return inline_unsafe_access( is_native_ptr, is_store, T_INT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
769 case vmIntrinsics::_putLong_raw: return inline_unsafe_access( is_native_ptr, is_store, T_LONG, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
770 case vmIntrinsics::_putFloat_raw: return inline_unsafe_access( is_native_ptr, is_store, T_FLOAT, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
771 case vmIntrinsics::_putDouble_raw: return inline_unsafe_access( is_native_ptr, is_store, T_DOUBLE, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
772 case vmIntrinsics::_putAddress_raw: return inline_unsafe_access( is_native_ptr, is_store, T_ADDRESS, !is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
773
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
774 case vmIntrinsics::_getObjectVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
775 case vmIntrinsics::_getBooleanVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
776 case vmIntrinsics::_getByteVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
777 case vmIntrinsics::_getShortVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
778 case vmIntrinsics::_getCharVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
779 case vmIntrinsics::_getIntVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
780 case vmIntrinsics::_getLongVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
781 case vmIntrinsics::_getFloatVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
782 case vmIntrinsics::_getDoubleVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
783
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
784 case vmIntrinsics::_putObjectVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
785 case vmIntrinsics::_putBooleanVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
786 case vmIntrinsics::_putByteVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
787 case vmIntrinsics::_putShortVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
788 case vmIntrinsics::_putCharVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
789 case vmIntrinsics::_putIntVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
790 case vmIntrinsics::_putLongVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
791 case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
792 case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, is_volatile);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
793
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
794 case vmIntrinsics::_prefetchRead: return inline_unsafe_prefetch(!is_native_ptr, !is_store, !is_static);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
795 case vmIntrinsics::_prefetchWrite: return inline_unsafe_prefetch(!is_native_ptr, is_store, !is_static);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
796 case vmIntrinsics::_prefetchReadStatic: return inline_unsafe_prefetch(!is_native_ptr, !is_store, is_static);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
797 case vmIntrinsics::_prefetchWriteStatic: return inline_unsafe_prefetch(!is_native_ptr, is_store, is_static);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
798
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
799 case vmIntrinsics::_compareAndSwapObject: return inline_unsafe_load_store(T_OBJECT, LS_cmpxchg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
800 case vmIntrinsics::_compareAndSwapInt: return inline_unsafe_load_store(T_INT, LS_cmpxchg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
801 case vmIntrinsics::_compareAndSwapLong: return inline_unsafe_load_store(T_LONG, LS_cmpxchg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
802
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
803 case vmIntrinsics::_putOrderedObject: return inline_unsafe_ordered_store(T_OBJECT);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
804 case vmIntrinsics::_putOrderedInt: return inline_unsafe_ordered_store(T_INT);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
805 case vmIntrinsics::_putOrderedLong: return inline_unsafe_ordered_store(T_LONG);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
806
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
807 case vmIntrinsics::_getAndAddInt: return inline_unsafe_load_store(T_INT, LS_xadd);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
808 case vmIntrinsics::_getAndAddLong: return inline_unsafe_load_store(T_LONG, LS_xadd);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
809 case vmIntrinsics::_getAndSetInt: return inline_unsafe_load_store(T_INT, LS_xchg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
810 case vmIntrinsics::_getAndSetLong: return inline_unsafe_load_store(T_LONG, LS_xchg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
811 case vmIntrinsics::_getAndSetObject: return inline_unsafe_load_store(T_OBJECT, LS_xchg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
812
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
813 case vmIntrinsics::_loadFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
814 case vmIntrinsics::_storeFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
815 case vmIntrinsics::_fullFence: return inline_unsafe_fence(intrinsic_id());
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
816
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
817 case vmIntrinsics::_currentThread: return inline_native_currentThread();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
818 case vmIntrinsics::_isInterrupted: return inline_native_isInterrupted();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
819
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
820 #ifdef TRACE_HAVE_INTRINSICS
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
821 case vmIntrinsics::_classID: return inline_native_classID();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
822 case vmIntrinsics::_threadID: return inline_native_threadID();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
823 case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
824 #endif
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
825 case vmIntrinsics::_currentTimeMillis: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
826 case vmIntrinsics::_nanoTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
827 case vmIntrinsics::_allocateInstance: return inline_unsafe_allocate();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
828 case vmIntrinsics::_copyMemory: return inline_unsafe_copyMemory();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
829 case vmIntrinsics::_newArray: return inline_native_newArray();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
830 case vmIntrinsics::_getLength: return inline_native_getLength();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
831 case vmIntrinsics::_copyOf: return inline_array_copyOf(false);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
832 case vmIntrinsics::_copyOfRange: return inline_array_copyOf(true);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
833 case vmIntrinsics::_equalsC: return inline_array_equals();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
834 case vmIntrinsics::_clone: return inline_native_clone(intrinsic()->is_virtual());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
835
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
836 case vmIntrinsics::_isAssignableFrom: return inline_native_subtype_check();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 case vmIntrinsics::_isInstance:
a61af66fc99e Initial load
duke
parents:
diff changeset
839 case vmIntrinsics::_getModifiers:
a61af66fc99e Initial load
duke
parents:
diff changeset
840 case vmIntrinsics::_isInterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
841 case vmIntrinsics::_isArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
842 case vmIntrinsics::_isPrimitive:
a61af66fc99e Initial load
duke
parents:
diff changeset
843 case vmIntrinsics::_getSuperclass:
a61af66fc99e Initial load
duke
parents:
diff changeset
844 case vmIntrinsics::_getComponentType:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
845 case vmIntrinsics::_getClassAccessFlags: return inline_native_Class_query(intrinsic_id());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 case vmIntrinsics::_floatToRawIntBits:
a61af66fc99e Initial load
duke
parents:
diff changeset
848 case vmIntrinsics::_floatToIntBits:
a61af66fc99e Initial load
duke
parents:
diff changeset
849 case vmIntrinsics::_intBitsToFloat:
a61af66fc99e Initial load
duke
parents:
diff changeset
850 case vmIntrinsics::_doubleToRawLongBits:
a61af66fc99e Initial load
duke
parents:
diff changeset
851 case vmIntrinsics::_doubleToLongBits:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
852 case vmIntrinsics::_longBitsToDouble: return inline_fp_conversions(intrinsic_id());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
853
775
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 730
diff changeset
854 case vmIntrinsics::_numberOfLeadingZeros_i:
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 730
diff changeset
855 case vmIntrinsics::_numberOfLeadingZeros_l:
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 730
diff changeset
856 case vmIntrinsics::_numberOfTrailingZeros_i:
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 730
diff changeset
857 case vmIntrinsics::_numberOfTrailingZeros_l:
643
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 605
diff changeset
858 case vmIntrinsics::_bitCount_i:
c771b7f43bbf 6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents: 605
diff changeset
859 case vmIntrinsics::_bitCount_l:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
860 case vmIntrinsics::_reverseBytes_i:
a61af66fc99e Initial load
duke
parents:
diff changeset
861 case vmIntrinsics::_reverseBytes_l:
1396
d7f654633cfe 6946040: add intrinsic for short and char reverseBytes
never
parents: 1152
diff changeset
862 case vmIntrinsics::_reverseBytes_s:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
863 case vmIntrinsics::_reverseBytes_c: return inline_number_methods(intrinsic_id());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
864
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
865 case vmIntrinsics::_getCallerClass: return inline_native_Reflection_getCallerClass();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
866
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
867 case vmIntrinsics::_Reference_get: return inline_reference_get();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
868
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
869 case vmIntrinsics::_aescrypt_encryptBlock:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
870 case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id());
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
871
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
872 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
873 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
874 return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
875
7637
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
876 case vmIntrinsics::_encodeISOArray:
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
877 return inline_encodeISOArray();
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
878
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
879 case vmIntrinsics::_updateCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
880 return inline_updateCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
881 case vmIntrinsics::_updateBytesCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
882 return inline_updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
883 case vmIntrinsics::_updateByteBufferCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
884 return inline_updateByteBufferCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
885
0
a61af66fc99e Initial load
duke
parents:
diff changeset
886 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
887 // If you get here, it may be that someone has added a new intrinsic
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // to the list in vmSymbols.hpp without implementing it here.
a61af66fc99e Initial load
duke
parents:
diff changeset
889 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
890 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
892 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
894 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
895 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
899 Node* LibraryCallKit::try_to_predicate() {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
900 if (!jvms()->has_method()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
901 // Root JVMState has a null method.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
902 assert(map()->memory()->Opcode() == Op_Parm, "");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
903 // Insert the memory aliasing node
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
904 set_all_memory(reset_memory());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
905 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
906 assert(merged_memory(), "");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
907
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
908 switch (intrinsic_id()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
909 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
910 return inline_cipherBlockChaining_AESCrypt_predicate(false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
911 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
912 return inline_cipherBlockChaining_AESCrypt_predicate(true);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
913
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
914 default:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
915 // If you get here, it may be that someone has added a new intrinsic
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
916 // to the list in vmSymbols.hpp without implementing it here.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
917 #ifndef PRODUCT
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
918 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
919 tty->print_cr("*** Warning: Unimplemented predicate for intrinsic %s(%d)",
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
920 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
921 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
922 #endif
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
923 Node* slow_ctl = control();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
924 set_control(top()); // No fast path instrinsic
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
925 return slow_ctl;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
926 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
927 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
928
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
929 //------------------------------set_result-------------------------------
0
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // Helper function for finishing intrinsics.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
931 void LibraryCallKit::set_result(RegionNode* region, PhiNode* value) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
932 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
933 set_control(_gvn.transform(region));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
934 set_result( _gvn.transform(value));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
935 assert(value->type()->basic_type() == result()->bottom_type()->basic_type(), "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937
a61af66fc99e Initial load
duke
parents:
diff changeset
938 //------------------------------generate_guard---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
939 // Helper function for generating guarded fast-slow graph structures.
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // The given 'test', if true, guards a slow path. If the test fails
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // then a fast path can be taken. (We generally hope it fails.)
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // In all cases, GraphKit::control() is updated to the fast path.
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // The returned value represents the control for the slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // The return value is never 'top'; it is either a valid control
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // or NULL if it is obvious that the slow path can never be taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // Also, if region and the slow control are not NULL, the slow edge
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // is appended to the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
948 Node* LibraryCallKit::generate_guard(Node* test, RegionNode* region, float true_prob) {
a61af66fc99e Initial load
duke
parents:
diff changeset
949 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Already short circuited.
a61af66fc99e Initial load
duke
parents:
diff changeset
951 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // Build an if node and its projections.
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // If test is true we take the slow path, which we assume is uncommon.
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if (_gvn.type(test) == TypeInt::ZERO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // The slow branch is never taken. No need to build this guard.
a61af66fc99e Initial load
duke
parents:
diff changeset
958 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
962
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
963 Node* if_slow = _gvn.transform(new (C) IfTrueNode(iff));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if (if_slow == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // The slow branch is never taken. No need to build this guard.
a61af66fc99e Initial load
duke
parents:
diff changeset
966 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 if (region != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
970 region->add_req(if_slow);
a61af66fc99e Initial load
duke
parents:
diff changeset
971
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
972 Node* if_fast = _gvn.transform(new (C) IfFalseNode(iff));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
973 set_control(if_fast);
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 return if_slow;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 inline Node* LibraryCallKit::generate_slow_guard(Node* test, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 return generate_guard(test, region, PROB_UNLIKELY_MAG(3));
a61af66fc99e Initial load
duke
parents:
diff changeset
980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
981 inline Node* LibraryCallKit::generate_fair_guard(Node* test, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
982 return generate_guard(test, region, PROB_FAIR);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
984
a61af66fc99e Initial load
duke
parents:
diff changeset
985 inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
986 Node* *pos_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
987 if (stopped())
a61af66fc99e Initial load
duke
parents:
diff changeset
988 return NULL; // already stopped
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint]
a61af66fc99e Initial load
duke
parents:
diff changeset
990 return NULL; // index is already adequately typed
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
991 Node* cmp_lt = _gvn.transform(new (C) CmpINode(index, intcon(0)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
992 Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
993 Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
a61af66fc99e Initial load
duke
parents:
diff changeset
994 if (is_neg != NULL && pos_index != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // Emulate effect of Parse::adjust_map_after_if.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
996 Node* ccast = new (C) CastIINode(index, TypeInt::POS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
997 ccast->set_req(0, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
998 (*pos_index) = _gvn.transform(ccast);
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 return is_neg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_negative,
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 Node* *pos_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 if (stopped())
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 return NULL; // already stopped
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint]
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 return NULL; // index is already adequately typed
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1009 Node* cmp_le = _gvn.transform(new (C) CmpINode(index, intcon(0)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1011 Node* bol_le = _gvn.transform(new (C) BoolNode(cmp_le, le_or_eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN);
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 if (is_notp != NULL && pos_index != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // Emulate effect of Parse::adjust_map_after_if.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1015 Node* ccast = new (C) CastIINode(index, TypeInt::POS1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 ccast->set_req(0, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 (*pos_index) = _gvn.transform(ccast);
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 return is_notp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // Make sure that 'position' is a valid limit index, in [0..length].
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // There are two equivalent plans for checking this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // A. (offset + copyLength) unsigned<= arrayLength
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // B. offset <= (arrayLength - copyLength)
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // We require that all of the values above, except for the sum and
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // difference, are already known to be non-negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // Plan A is robust in the face of overflow, if offset and copyLength
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // are both hugely positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // Plan B is less direct and intuitive, but it does not overflow at
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // all, since the difference of two non-negatives is always
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // representable. Whenever Java methods must perform the equivalent
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // check they generally use Plan B instead of Plan A.
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // For the moment we use Plan A.
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 inline Node* LibraryCallKit::generate_limit_guard(Node* offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 Node* subseq_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 Node* array_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 if (stopped())
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 return NULL; // already stopped
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 bool zero_offset = _gvn.type(offset) == TypeInt::ZERO;
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
1043 if (zero_offset && subseq_length->eqv_uncast(array_length))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 return NULL; // common case of whole-array copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 Node* last = subseq_length;
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 if (!zero_offset) // last += offset
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1047 last = _gvn.transform(new (C) AddINode(last, offset));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1048 Node* cmp_lt = _gvn.transform(new (C) CmpUNode(array_length, last));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1049 Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 return is_over;
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1053
a61af66fc99e Initial load
duke
parents:
diff changeset
1054
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 //--------------------------generate_current_thread--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 ciKlass* thread_klass = env()->Thread_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1059 Node* thread = _gvn.transform(new (C) ThreadLocalNode());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
1061 Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 tls_output = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 return threadObj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1067 //------------------------------make_string_method_node------------------------
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1068 // Helper method for String intrinsic functions. This version is called
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1069 // with str1 and str2 pointing to String object nodes.
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1070 //
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1071 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* str2) {
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1072 Node* no_ctrl = NULL;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1073
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1074 // Get start addr of string
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1075 Node* str1_value = load_String_value(no_ctrl, str1);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1076 Node* str1_offset = load_String_offset(no_ctrl, str1);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1077 Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1078
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1079 // Get length of string 1
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1080 Node* str1_len = load_String_length(no_ctrl, str1);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1081
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1082 Node* str2_value = load_String_value(no_ctrl, str2);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1083 Node* str2_offset = load_String_offset(no_ctrl, str2);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1084 Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1085
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1086 Node* str2_len = NULL;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1087 Node* result = NULL;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1088
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1089 switch (opcode) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1090 case Op_StrIndexOf:
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1091 // Get length of string 2
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1092 str2_len = load_String_length(no_ctrl, str2);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1093
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1094 result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1095 str1_start, str1_len, str2_start, str2_len);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1096 break;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1097 case Op_StrComp:
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1098 // Get length of string 2
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1099 str2_len = load_String_length(no_ctrl, str2);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1100
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1101 result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS),
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1102 str1_start, str1_len, str2_start, str2_len);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1103 break;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1104 case Op_StrEquals:
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1105 result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1106 str1_start, str2_start, str1_len);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1107 break;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1108 default:
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1109 ShouldNotReachHere();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1110 return NULL;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1111 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1112
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1113 // All these intrinsics have checks.
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1114 C->set_has_split_ifs(true); // Has chance for split-if optimization
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1115
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1116 return _gvn.transform(result);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1117 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1118
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1119 // Helper method for String intrinsic functions. This version is called
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1120 // with str1 and str2 pointing to char[] nodes, with cnt1 and cnt2 pointing
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1121 // to Int nodes containing the lenghts of str1 and str2.
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1122 //
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1123 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2) {
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1124 Node* result = NULL;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1125 switch (opcode) {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1126 case Op_StrIndexOf:
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1127 result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1128 str1_start, cnt1, str2_start, cnt2);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1129 break;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1130 case Op_StrComp:
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1131 result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS),
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1132 str1_start, cnt1, str2_start, cnt2);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1133 break;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1134 case Op_StrEquals:
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1135 result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1136 str1_start, str2_start, cnt1);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1137 break;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1138 default:
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1139 ShouldNotReachHere();
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1140 return NULL;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1141 }
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1142
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1143 // All these intrinsics have checks.
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1144 C->set_has_split_ifs(true); // Has chance for split-if optimization
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1145
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1146 return _gvn.transform(result);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1147 }
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1148
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 //------------------------------inline_string_compareTo------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1150 // public int java.lang.String.compareTo(String anotherString);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 bool LibraryCallKit::inline_string_compareTo() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1152 Node* receiver = null_check(argument(0));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1153 Node* arg = null_check(argument(1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1157 set_result(make_string_method_node(Op_StrComp, receiver, arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1161 //------------------------------inline_string_equals------------------------
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1162 bool LibraryCallKit::inline_string_equals() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1163 Node* receiver = null_check_receiver();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1164 // NOTE: Do not null check argument for String.equals() because spec
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1165 // allows to specify NULL as argument.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1166 Node* argument = this->argument(1);
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1167 if (stopped()) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1168 return true;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1169 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1170
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1171 // paths (plus control) merge
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1172 RegionNode* region = new (C) RegionNode(5);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1173 Node* phi = new (C) PhiNode(region, TypeInt::BOOL);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1174
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1175 // does source == target string?
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1176 Node* cmp = _gvn.transform(new (C) CmpPNode(receiver, argument));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1177 Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq));
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1178
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1179 Node* if_eq = generate_slow_guard(bol, NULL);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1180 if (if_eq != NULL) {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1181 // receiver == argument
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1182 phi->init_req(2, intcon(1));
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1183 region->init_req(2, if_eq);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1184 }
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1185
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1186 // get String klass for instanceOf
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1187 ciInstanceKlass* klass = env()->String_klass();
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1188
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1189 if (!stopped()) {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1190 Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1191 Node* cmp = _gvn.transform(new (C) CmpINode(inst, intcon(1)));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1192 Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne));
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1193
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1194 Node* inst_false = generate_guard(bol, NULL, PROB_MIN);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1195 //instanceOf == true, fallthrough
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1196
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1197 if (inst_false != NULL) {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1198 phi->init_req(3, intcon(0));
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1199 region->init_req(3, inst_false);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1200 }
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1201 }
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1202
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1203 if (!stopped()) {
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1204 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1205
1496
e8e83be27dd7 6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents: 1396
diff changeset
1206 // Properly cast the argument to String
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1207 argument = _gvn.transform(new (C) CheckCastPPNode(control(), argument, string_type));
3337
e6d7eed3330c 7041100: The load in String.equals intrinsic executed before null check
kvn
parents: 3284
diff changeset
1208 // This path is taken only when argument's type is String:NotNull.
e6d7eed3330c 7041100: The load in String.equals intrinsic executed before null check
kvn
parents: 3284
diff changeset
1209 argument = cast_not_null(argument, false);
1496
e8e83be27dd7 6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents: 1396
diff changeset
1210
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1211 Node* no_ctrl = NULL;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1212
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1213 // Get start addr of receiver
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1214 Node* receiver_val = load_String_value(no_ctrl, receiver);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1215 Node* receiver_offset = load_String_offset(no_ctrl, receiver);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1216 Node* receiver_start = array_element_address(receiver_val, receiver_offset, T_CHAR);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1217
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1218 // Get length of receiver
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1219 Node* receiver_cnt = load_String_length(no_ctrl, receiver);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1220
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1221 // Get start addr of argument
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1222 Node* argument_val = load_String_value(no_ctrl, argument);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1223 Node* argument_offset = load_String_offset(no_ctrl, argument);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1224 Node* argument_start = array_element_address(argument_val, argument_offset, T_CHAR);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1225
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1226 // Get length of argument
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1227 Node* argument_cnt = load_String_length(no_ctrl, argument);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1228
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1229 // Check for receiver count != argument count
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1230 Node* cmp = _gvn.transform(new(C) CmpINode(receiver_cnt, argument_cnt));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1231 Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::ne));
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1232 Node* if_ne = generate_slow_guard(bol, NULL);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1233 if (if_ne != NULL) {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1234 phi->init_req(4, intcon(0));
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1235 region->init_req(4, if_ne);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1236 }
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1237
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1238 // Check for count == 0 is done by assembler code for StrEquals.
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1239
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1240 if (!stopped()) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1241 Node* equals = make_string_method_node(Op_StrEquals, receiver_start, receiver_cnt, argument_start, argument_cnt);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1242 phi->init_req(1, equals);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1243 region->init_req(1, control());
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1244 }
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1245 }
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1246
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1247 // post merge
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1248 set_control(_gvn.transform(region));
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1249 record_for_igvn(region);
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1250
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1251 set_result(_gvn.transform(phi));
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1252 return true;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1253 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1254
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
1255 //------------------------------inline_array_equals----------------------------
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
1256 bool LibraryCallKit::inline_array_equals() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1257 Node* arg1 = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1258 Node* arg2 = argument(1);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1259 set_result(_gvn.transform(new (C) AryEqNode(control(), memory(TypeAryPtr::CHARS), arg1, arg2)));
169
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
1260 return true;
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
1261 }
9148c65abefc 6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents: 164
diff changeset
1262
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Java version of String.indexOf(constant string)
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // class StringDecl {
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // StringDecl(char[] ca) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // count = ca.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 // value = ca;
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 // int count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // char[] value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // static int string_indexOf_J(StringDecl string_object, char[] target_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // int targetOffset, int cache_i, int md2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // int cache = cache_i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // int sourceOffset = string_object.offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // int sourceCount = string_object.count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // int targetCount = target_object.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // int targetCountLess1 = targetCount - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // int sourceEnd = sourceOffset + sourceCount - targetCountLess1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // char[] source = string_object.value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // char[] target = target_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // int lastChar = target[targetCountLess1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // outer_loop:
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // for (int i = sourceOffset; i < sourceEnd; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // int src = source[i + targetCountLess1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // if (src == lastChar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // // With random strings and a 4-character alphabet,
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // // reverse matching at this point sets up 0.8% fewer
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // // frames, but (paradoxically) makes 0.3% more probes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // // Since those probes are nearer the lastChar probe,
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // // there is may be a net D$ win with reverse matching.
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // // But, reversing loop inhibits unroll of inner loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // // for unknown reason. So, does running outer loop from
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // // (sourceOffset - targetCountLess1) to (sourceOffset + sourceCount)
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // for (int j = 0; j < targetCountLess1; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // if (target[targetOffset + j] != source[i+j]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // if ((cache & (1 << source[i+j])) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // if (md2 < j+1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // i += j+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // continue outer_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // i += md2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // continue outer_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // return i - sourceOffset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // if ((cache & (1 << src)) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // i += targetCountLess1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // } // using "i += targetCount;" and an "else i++;" causes a jump to jump.
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 //------------------------------string_indexOf------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_array, jint targetOffset_i,
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 jint cache_i, jint md2_i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 Node* no_ctrl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 float likely = PROB_LIKELY(0.9);
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 float unlikely = PROB_UNLIKELY(0.9);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1331 const int nargs = 0; // no arguments to push back for uncommon trap in predicate
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2324
diff changeset
1332
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1333 Node* source = load_String_value(no_ctrl, string_object);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1334 Node* sourceOffset = load_String_offset(no_ctrl, string_object);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1335 Node* sourceCount = load_String_length(no_ctrl, string_object);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1337 Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 jint target_length = target_array->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
12190
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
1342 // String.value field is known to be @Stable.
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
1343 if (UseImplicitStableValues) {
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
1344 target = cast_array_to_stable(target, target_type);
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
1345 }
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
1346
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
1347 IdealKit kit(this, false, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 #define __ kit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 Node* zero = __ ConI(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 Node* one = __ ConI(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 Node* cache = __ ConI(cache_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 Node* md2 = __ ConI(md2_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 Node* lastChar = __ ConI(target_array->char_at(target_length - 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 Node* targetCount = __ ConI(target_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 Node* targetCountLess1 = __ ConI(target_length - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 Node* targetOffset = __ ConI(targetOffset_i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 Node* sourceEnd = __ SubI(__ AddI(sourceOffset, sourceCount), targetCountLess1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
1359 IdealVariable rtn(kit), i(kit), j(kit); __ declarations_done();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 Node* outer_loop = __ make_label(2 /* goto */);
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 Node* return_ = __ make_label(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1362
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 __ set(rtn,__ ConI(-1));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2324
diff changeset
1364 __ loop(this, nargs, i, sourceOffset, BoolTest::lt, sourceEnd); {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 Node* i2 = __ AddI(__ value(i), targetCountLess1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // pin to prohibit loading of "next iteration" value which may SEGV (rare)
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 Node* src = load_array_element(__ ctrl(), source, i2, TypeAryPtr::CHARS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 __ if_then(src, BoolTest::eq, lastChar, unlikely); {
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2324
diff changeset
1369 __ loop(this, nargs, j, zero, BoolTest::lt, targetCountLess1); {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 Node* tpj = __ AddI(targetOffset, __ value(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 Node* targ = load_array_element(no_ctrl, target, tpj, target_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 Node* ipj = __ AddI(__ value(i), __ value(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 Node* src2 = load_array_element(no_ctrl, source, ipj, TypeAryPtr::CHARS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 __ if_then(targ, BoolTest::ne, src2); {
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 __ if_then(__ AndI(cache, __ LShiftI(one, src2)), BoolTest::eq, zero); {
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 __ if_then(md2, BoolTest::lt, __ AddI(__ value(j), one)); {
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 __ increment(i, __ AddI(__ value(j), one));
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 __ goto_(outer_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 } __ end_if(); __ dead(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 }__ end_if(); __ dead(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 __ increment(i, md2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 __ goto_(outer_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 }__ end_if();
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 __ increment(j, one);
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }__ end_loop(); __ dead(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 __ set(rtn, __ SubI(__ value(i), sourceOffset)); __ dead(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 __ goto_(return_);
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 }__ end_if();
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 __ if_then(__ AndI(cache, __ LShiftI(one, src)), BoolTest::eq, zero, likely); {
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 __ increment(i, targetCountLess1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 }__ end_if();
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 __ increment(i, one);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 __ bind(outer_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }__ end_loop(); __ dead(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 __ bind(return_);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
1396
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
1397 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
1398 final_sync(kit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 Node* result = __ value(rtn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 #undef __
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 C->set_has_loops(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 //------------------------------inline_string_indexOf------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 bool LibraryCallKit::inline_string_indexOf() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1407 Node* receiver = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1408 Node* arg = argument(1);
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1409
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1410 Node* result;
1504
ae8f909e5fc7 6948602: Disable use of SSE4.2 in String.indexOf intrinsic until 6942326 is fixed
iveresov
parents: 1396
diff changeset
1411 // Disable the use of pcmpestri until it can be guaranteed that
ae8f909e5fc7 6948602: Disable use of SSE4.2 in String.indexOf intrinsic until 6942326 is fixed
iveresov
parents: 1396
diff changeset
1412 // the load doesn't cross into the uncommited space.
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1413 if (Matcher::has_match_rule(Op_StrIndexOf) &&
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1414 UseSSE42Intrinsics) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1415 // Generate SSE4.2 version of indexOf
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1416 // We currently only have match rules that use SSE4.2
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1417
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1418 receiver = null_check(receiver);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1419 arg = null_check(arg);
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1420 if (stopped()) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1421 return true;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1422 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1423
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1424 ciInstanceKlass* str_klass = env()->String_klass();
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1425 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1426
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1427 // Make the merge point
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1428 RegionNode* result_rgn = new (C) RegionNode(4);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1429 Node* result_phi = new (C) PhiNode(result_rgn, TypeInt::INT);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1430 Node* no_ctrl = NULL;
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1431
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1432 // Get start addr of source string
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1433 Node* source = load_String_value(no_ctrl, receiver);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1434 Node* source_offset = load_String_offset(no_ctrl, receiver);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1435 Node* source_start = array_element_address(source, source_offset, T_CHAR);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1436
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1437 // Get length of source string
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1438 Node* source_cnt = load_String_length(no_ctrl, receiver);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1439
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1440 // Get start addr of substring
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1441 Node* substr = load_String_value(no_ctrl, arg);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1442 Node* substr_offset = load_String_offset(no_ctrl, arg);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1443 Node* substr_start = array_element_address(substr, substr_offset, T_CHAR);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1444
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1445 // Get length of source string
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1446 Node* substr_cnt = load_String_length(no_ctrl, arg);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1447
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1448 // Check for substr count > string count
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1449 Node* cmp = _gvn.transform(new(C) CmpINode(substr_cnt, source_cnt));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1450 Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::gt));
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1451 Node* if_gt = generate_slow_guard(bol, NULL);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1452 if (if_gt != NULL) {
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1453 result_phi->init_req(2, intcon(-1));
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1454 result_rgn->init_req(2, if_gt);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1455 }
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1456
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1457 if (!stopped()) {
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1458 // Check for substr count == 0
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1459 cmp = _gvn.transform(new(C) CmpINode(substr_cnt, intcon(0)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1460 bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq));
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1461 Node* if_zero = generate_slow_guard(bol, NULL);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1462 if (if_zero != NULL) {
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1463 result_phi->init_req(3, intcon(0));
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1464 result_rgn->init_req(3, if_zero);
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1465 }
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1466 }
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1467
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1468 if (!stopped()) {
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1469 result = make_string_method_node(Op_StrIndexOf, source_start, source_cnt, substr_start, substr_cnt);
986
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1470 result_phi->init_req(1, result);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1471 result_rgn->init_req(1, control());
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1472 }
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1473 set_control(_gvn.transform(result_rgn));
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1474 record_for_igvn(result_rgn);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1475 result = _gvn.transform(result_phi);
62001a362ce9 6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents: 958
diff changeset
1476
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1477 } else { // Use LibraryCallKit::string_indexOf
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1478 // don't intrinsify if argument isn't a constant string.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1479 if (!arg->is_Con()) {
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1480 return false;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1481 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1482 const TypeOopPtr* str_type = _gvn.type(arg)->isa_oopptr();
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1483 if (str_type == NULL) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1484 return false;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1485 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1486 ciInstanceKlass* klass = env()->String_klass();
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1487 ciObject* str_const = str_type->const_oop();
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1488 if (str_const == NULL || str_const->klass() != klass) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1489 return false;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1490 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1491 ciInstance* str = str_const->as_instance();
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1492 assert(str != NULL, "must be instance");
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1493
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1494 ciObject* v = str->field_value_by_offset(java_lang_String::value_offset_in_bytes()).as_object();
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1495 ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1496
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1497 int o;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1498 int c;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1499 if (java_lang_String::has_offset_field()) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1500 o = str->field_value_by_offset(java_lang_String::offset_offset_in_bytes()).as_int();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1501 c = str->field_value_by_offset(java_lang_String::count_offset_in_bytes()).as_int();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1502 } else {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1503 o = 0;
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1504 c = pat->length();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1505 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6006
diff changeset
1506
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1507 // constant strings have no offset and count == length which
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1508 // simplifies the resulting code somewhat so lets optimize for that.
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1509 if (o != 0 || c != pat->length()) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1510 return false;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1511 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1512
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1513 receiver = null_check(receiver, T_OBJECT);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1514 // NOTE: No null check on the argument is needed since it's a constant String oop.
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1515 if (stopped()) {
2320
41d4973cf100 6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents: 1972
diff changeset
1516 return true;
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1517 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1518
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1519 // The null string as a pattern always returns 0 (match at beginning of string)
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1520 if (c == 0) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1521 set_result(intcon(0));
681
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1522 return true;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1523 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1524
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1525 // Generate default indexOf
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1526 jchar lastChar = pat->char_at(o + (c - 1));
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1527 int cache = 0;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1528 int i;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1529 for (i = 0; i < c - 1; i++) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1530 assert(i < pat->length(), "out of range");
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1531 cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1532 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1533
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1534 int md2 = c;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1535 for (i = 0; i < c - 1; i++) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1536 assert(i < pat->length(), "out of range");
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1537 if (pat->char_at(o + i) == lastChar) {
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1538 md2 = (c - 1) - i;
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1539 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1540 }
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1541
fbde8ec322d0 6761600: Use sse 4.2 in intrinsics
cfang
parents: 643
diff changeset
1542 result = string_indexOf(receiver, pat, o, cache, md2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1544 set_result(result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1548 //--------------------------round_double_node--------------------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1549 // Round a double node if necessary.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1550 Node* LibraryCallKit::round_double_node(Node* n) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1551 if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1552 n = _gvn.transform(new (C) RoundDoubleNode(0, n));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1553 return n;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1554 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1555
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1556 //------------------------------inline_math-----------------------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1557 // public static double Math.abs(double)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1558 // public static double Math.sqrt(double)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1559 // public static double Math.log(double)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1560 // public static double Math.log10(double)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1561 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1562 Node* arg = round_double_node(argument(0));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1563 Node* n;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1564 switch (id) {
8076
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1565 case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break;
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1566 case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(C, control(), arg); break;
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1567 case vmIntrinsics::_dlog: n = new (C) LogDNode(C, control(), arg); break;
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1568 case vmIntrinsics::_dlog10: n = new (C) Log10DNode(C, control(), arg); break;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1569 default: fatal_unexpected_iid(id); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1570 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1571 set_result(_gvn.transform(n));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1572 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1574
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 //------------------------------inline_trig----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // Inline sin/cos/tan instructions, if possible. If rounding is required, do
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // argument reduction which will turn into a fast/slow diamond.
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1579 Node* arg = round_double_node(argument(0));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1580 Node* n = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1581
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 switch (id) {
8076
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1583 case vmIntrinsics::_dsin: n = new (C) SinDNode(C, control(), arg); break;
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1584 case vmIntrinsics::_dcos: n = new (C) CosDNode(C, control(), arg); break;
c59b7900a2bd 8007959: Use expensive node logic for more math nodes
roland
parents: 8048
diff changeset
1585 case vmIntrinsics::_dtan: n = new (C) TanDNode(C, control(), arg); break;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1586 default: fatal_unexpected_iid(id); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1588 n = _gvn.transform(n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1589
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // Rounding required? Check for argument reduction!
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1591 if (Matcher::strict_fp_requires_explicit_rounding) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 static const double pi_4 = 0.7853981633974483;
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 static const double neg_pi_4 = -0.7853981633974483;
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // pi/2 in 80-bit extended precision
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 // static const unsigned char pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00};
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // -pi/2 in 80-bit extended precision
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // static const unsigned char neg_pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00};
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // Cutoff value for using this argument reduction technique
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 //static const double pi_2_minus_epsilon = 1.564660403643354;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 //static const double neg_pi_2_plus_epsilon = -1.564660403643354;
a61af66fc99e Initial load
duke
parents:
diff changeset
1601
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 // Pseudocode for sin:
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // if (x <= Math.PI / 4.0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // if (x >= -Math.PI / 4.0) return fsin(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // if (x >= -Math.PI / 2.0) return -fcos(x + Math.PI / 2.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // if (x <= Math.PI / 2.0) return fcos(x - Math.PI / 2.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // return StrictMath.sin(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1610
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // Pseudocode for cos:
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // if (x <= Math.PI / 4.0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // if (x >= -Math.PI / 4.0) return fcos(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // if (x >= -Math.PI / 2.0) return fsin(x + Math.PI / 2.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // if (x <= Math.PI / 2.0) return -fsin(x - Math.PI / 2.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // return StrictMath.cos(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1619
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // Actually, sticking in an 80-bit Intel value into C2 will be tough; it
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 // requires a special machine instruction to load it. Instead we'll try
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // the 'easy' case. If we really need the extra range +/- PI/2 we'll
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // probably do the math inside the SIN encoding.
a61af66fc99e Initial load
duke
parents:
diff changeset
1624
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // Make the merge point
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1626 RegionNode* r = new (C) RegionNode(3);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1627 Node* phi = new (C) PhiNode(r, Type::DOUBLE);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1628
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 // Flatten arg so we need only 1 test
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1630 Node *abs = _gvn.transform(new (C) AbsDNode(arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // Node for PI/4 constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 Node *pi4 = makecon(TypeD::make(pi_4));
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // Check PI/4 : abs(arg)
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1634 Node *cmp = _gvn.transform(new (C) CmpDNode(pi4,abs));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // Check: If PI/4 < abs(arg) then go slow
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1636 Node *bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::lt ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // Branch either way
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 set_control(opt_iff(r,iff));
a61af66fc99e Initial load
duke
parents:
diff changeset
1640
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // Set fast path result
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1642 phi->init_req(2, n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1643
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // Slow path - non-blocking leaf call
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 Node* call = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 case vmIntrinsics::_dsin:
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 call = make_runtime_call(RC_LEAF, OptoRuntime::Math_D_D_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 CAST_FROM_FN_PTR(address, SharedRuntime::dsin),
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 "Sin", NULL, arg, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 case vmIntrinsics::_dcos:
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 call = make_runtime_call(RC_LEAF, OptoRuntime::Math_D_D_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 CAST_FROM_FN_PTR(address, SharedRuntime::dcos),
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 "Cos", NULL, arg, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 case vmIntrinsics::_dtan:
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 call = make_runtime_call(RC_LEAF, OptoRuntime::Math_D_D_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 CAST_FROM_FN_PTR(address, SharedRuntime::dtan),
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 "Tan", NULL, arg, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 assert(control()->in(0) == call, "");
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1664 Node* slow_result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1665 r->init_req(1, control());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1666 phi->init_req(1, slow_result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1667
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // Post-merge
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 set_control(_gvn.transform(r));
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 record_for_igvn(r);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1671 n = _gvn.transform(phi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1675 set_result(n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1679 void LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1680 //-------------------
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1681 //result=(result.isNaN())? funcAddr():result;
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1682 // Check: If isNaN() by checking result!=result? then either trap
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1683 // or go to runtime
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1684 Node* cmpisnan = _gvn.transform(new (C) CmpDNode(result, result));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1685 // Build the boolean node
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1686 Node* bolisnum = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::eq));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1687
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1688 if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1689 { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1690 // The pow or exp intrinsic returned a NaN, which requires a call
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1691 // to the runtime. Recompile with the runtime call.
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1692 uncommon_trap(Deoptimization::Reason_intrinsic,
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1693 Deoptimization::Action_make_not_entrant);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1694 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1695 set_result(result);
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1696 } else {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1697 // If this inlining ever returned NaN in the past, we compile a call
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1698 // to the runtime to properly handle corner cases
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1699
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1700 IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1701 Node* if_slow = _gvn.transform(new (C) IfFalseNode(iff));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1702 Node* if_fast = _gvn.transform(new (C) IfTrueNode(iff));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1703
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1704 if (!if_slow->is_top()) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1705 RegionNode* result_region = new (C) RegionNode(3);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1706 PhiNode* result_val = new (C) PhiNode(result_region, Type::DOUBLE);
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1707
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1708 result_region->init_req(1, if_fast);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1709 result_val->init_req(1, result);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1710
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1711 set_control(if_slow);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1712
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1713 const TypePtr* no_memory_effects = NULL;
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1714 Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1715 no_memory_effects,
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1716 x, top(), y, y ? top() : NULL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1717 Node* value = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+0));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1718 #ifdef ASSERT
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1719 Node* value_top = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+1));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1720 assert(value_top == top(), "second value must be top");
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1721 #endif
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1722
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1723 result_region->init_req(2, control());
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1724 result_val->init_req(2, value);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1725 set_result(result_region, result_val);
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1726 } else {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1727 set_result(result);
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1728 }
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1729 }
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1730 }
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1731
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 //------------------------------inline_exp-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // Inline exp instructions, if possible. The Intel hardware only misses
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // really odd corner cases (+/- Infinity). Just uncommon-trap them.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1735 bool LibraryCallKit::inline_exp() {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1736 Node* arg = round_double_node(argument(0));
8048
8b3da8d14c93 7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents: 7637
diff changeset
1737 Node* n = _gvn.transform(new (C) ExpDNode(C, control(), arg));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1738
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1739 finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 //------------------------------inline_pow-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // Inline power instructions, if possible.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1747 bool LibraryCallKit::inline_pow() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 // Pseudocode for pow
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 // if (x <= 0.0) {
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1750 // long longy = (long)y;
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1751 // if ((double)longy == y) { // if y is long
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1752 // if (y + 1 == y) longy = 0; // huge number: even
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1753 // result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // result = NaN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // result = DPow(x,y);
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // if (result != result)? {
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1761 // result = uncommon_trap() or runtime_call();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1765 Node* x = round_double_node(argument(0));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1766 Node* y = round_double_node(argument(2));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1768 Node* result = NULL;
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1769
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1770 if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1771 // Short form: skip the fancy tests and just check for NaN result.
8048
8b3da8d14c93 7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents: 7637
diff changeset
1772 result = _gvn.transform(new (C) PowDNode(C, control(), x, y));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 } else {
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1774 // If this inlining ever returned NaN in the past, include all
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1775 // checks + call to the runtime.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1776
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 // Set the merge point for If node with condition of (x <= 0.0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // There are four possible paths to region node and phi node
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1779 RegionNode *r = new (C) RegionNode(4);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1780 Node *phi = new (C) PhiNode(r, Type::DOUBLE);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1781
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 // Build the first if node: if (x <= 0.0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 // Node for 0 constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 Node *zeronode = makecon(TypeD::ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 // Check x:0
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1786 Node *cmp = _gvn.transform(new (C) CmpDNode(x, zeronode));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // Check: If (x<=0) then go complex path
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1788 Node *bol1 = _gvn.transform(new (C) BoolNode( cmp, BoolTest::le ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // Branch either way
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // Fast path taken; set region slot 3
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1792 Node *fast_taken = _gvn.transform(new (C) IfFalseNode(if1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 r->init_req(3,fast_taken); // Capture fast-control
a61af66fc99e Initial load
duke
parents:
diff changeset
1794
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // Fast path not-taken, i.e. slow path
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1796 Node *complex_path = _gvn.transform(new (C) IfTrueNode(if1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 // Set fast path result
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1799 Node *fast_result = _gvn.transform(new (C) PowDNode(C, control(), x, y));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 phi->init_req(3, fast_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // Complex path
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1803 // Build the second if node (if y is long)
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1804 // Node for (long)y
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1805 Node *longy = _gvn.transform(new (C) ConvD2LNode(y));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1806 // Node for (double)((long) y)
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1807 Node *doublelongy= _gvn.transform(new (C) ConvL2DNode(longy));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1808 // Check (double)((long) y) : y
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1809 Node *cmplongy= _gvn.transform(new (C) CmpDNode(doublelongy, y));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1810 // Check if (y isn't long) then go to slow path
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1811
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1812 Node *bol2 = _gvn.transform(new (C) BoolNode( cmplongy, BoolTest::ne ));
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
1813 // Branch either way
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1815 Node* ylong_path = _gvn.transform(new (C) IfFalseNode(if2));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1816
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1817 Node *slow_path = _gvn.transform(new (C) IfTrueNode(if2));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1818
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1819 // Calculate DPow(abs(x), y)*(1 & (long)y)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 // Node for constant 1
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1821 Node *conone = longcon(1);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1822 // 1& (long)y
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1823 Node *signnode= _gvn.transform(new (C) AndLNode(conone, longy));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1824
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1825 // A huge number is always even. Detect a huge number by checking
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1826 // if y + 1 == y and set integer to be tested for parity to 0.
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1827 // Required for corner case:
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1828 // (long)9.223372036854776E18 = max_jlong
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1829 // (double)(long)9.223372036854776E18 = 9.223372036854776E18
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1830 // max_jlong is odd but 9.223372036854776E18 is even
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1831 Node* yplus1 = _gvn.transform(new (C) AddDNode(y, makecon(TypeD::make(1))));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1832 Node *cmpyplus1= _gvn.transform(new (C) CmpDNode(yplus1, y));
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1833 Node *bolyplus1 = _gvn.transform(new (C) BoolNode( cmpyplus1, BoolTest::eq ));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1834 Node* correctedsign = NULL;
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1835 if (ConditionalMoveLimit != 0) {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1836 correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG));
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1837 } else {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1838 IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1839 RegionNode *r = new (C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1840 Node *phi = new (C) PhiNode(r, TypeLong::LONG);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1841 r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyplus1)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1842 r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyplus1)));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1843 phi->init_req(1, signnode);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1844 phi->init_req(2, longcon(0));
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1845 correctedsign = _gvn.transform(phi);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1846 ylong_path = _gvn.transform(r);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1847 record_for_igvn(r);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1848 }
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1849
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // zero node
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1851 Node *conzero = longcon(0);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1852 // Check (1&(long)y)==0?
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1853 Node *cmpeq1 = _gvn.transform(new (C) CmpLNode(correctedsign, conzero));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1854 // Check if (1&(long)y)!=0?, if so the result is negative
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1855 Node *bol3 = _gvn.transform(new (C) BoolNode( cmpeq1, BoolTest::ne ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // abs(x)
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1857 Node *absx=_gvn.transform(new (C) AbsDNode(x));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 // abs(x)^y
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1859 Node *absxpowy = _gvn.transform(new (C) PowDNode(C, control(), absx, y));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // -abs(x)^y
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1861 Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1862 // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1863 Node *signresult = NULL;
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1864 if (ConditionalMoveLimit != 0) {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1865 signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1866 } else {
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1867 IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1868 RegionNode *r = new (C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1869 Node *phi = new (C) PhiNode(r, Type::DOUBLE);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1870 r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyeven)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
1871 r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyeven)));
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1872 phi->init_req(1, absxpowy);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1873 phi->init_req(2, negabsxpowy);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1874 signresult = _gvn.transform(phi);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1875 ylong_path = _gvn.transform(r);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1876 record_for_igvn(r);
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1877 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 // Set complex path fast result
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1879 r->init_req(2, ylong_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 phi->init_req(2, signresult);
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 static const jlong nan_bits = CONST64(0x7ff8000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 Node *slow_result = makecon(TypeD::make(*(double*)&nan_bits)); // return NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 r->init_req(1,slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 phi->init_req(1,slow_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1886
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 // Post merge
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 set_control(_gvn.transform(r));
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 record_for_igvn(r);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1890 result = _gvn.transform(phi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1892
6205
d50605d9417e 7177917: Failed test java/lang/Math/PowTests.java
roland
parents: 6180
diff changeset
1893 finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1894
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 //------------------------------runtime_math-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 "must be (DD)D or (D)D type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 // Inputs
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1905 Node* a = round_double_node(argument(0));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1906 Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? round_double_node(argument(2)) : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1907
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 const TypePtr* no_memory_effects = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 no_memory_effects,
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 a, top(), b, b ? top() : NULL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1912 Node* value = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 #ifdef ASSERT
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
1914 Node* value_top = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 assert(value_top == top(), "second value must be top");
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1917
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1918 set_result(value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1921
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 //------------------------------inline_math_native-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1924 #define FN_PTR(f) CAST_FROM_FN_PTR(address, f)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 // These intrinsics are not properly supported on all hardware
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1927 case vmIntrinsics::_dcos: return Matcher::has_match_rule(Op_CosD) ? inline_trig(id) :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1928 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos), "COS");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1929 case vmIntrinsics::_dsin: return Matcher::has_match_rule(Op_SinD) ? inline_trig(id) :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1930 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin), "SIN");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1931 case vmIntrinsics::_dtan: return Matcher::has_match_rule(Op_TanD) ? inline_trig(id) :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1932 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1933
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1934 case vmIntrinsics::_dlog: return Matcher::has_match_rule(Op_LogD) ? inline_math(id) :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1935 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog), "LOG");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1936 case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_math(id) :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1937 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // These intrinsics are supported on all hardware
14463
0f19095fd8c1 8035394: PPC64: Make usage of intrinsic dsqrt depend on processor recognition.
goetz
parents: 14456
diff changeset
1940 case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1941 case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_math(id) : false;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1942
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1943 case vmIntrinsics::_dexp: return Matcher::has_match_rule(Op_ExpD) ? inline_exp() :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1944 runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1945 case vmIntrinsics::_dpow: return Matcher::has_match_rule(Op_PowD) ? inline_pow() :
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1946 runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1947 #undef FN_PTR
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // These intrinsics are not yet correctly implemented
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 case vmIntrinsics::_datan2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1952
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1954 fatal_unexpected_iid(id);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1958
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 static bool is_simple_name(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 return (n->req() == 1 // constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 || (n->is_Type() && n->as_Type()->type()->singleton())
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 || n->is_Proj() // parameter or return value
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 || n->is_Phi() // local of some sort
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 //----------------------------inline_min_max-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1969 set_result(generate_min_max(id, argument(0), argument(1)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1972
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1973 void LibraryCallKit::inline_math_mathExact(Node* math) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1974 // If we didn't get the expected opcode it means we have optimized
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1975 // the node to something else and don't need the exception edge.
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1976 if (!math->is_MathExact()) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1977 set_result(math);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1978 return;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1979 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
1980
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1981 Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1982 Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1983
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1984 Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1985 IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1986 Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1987 Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1988
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1989 {
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1990 PreserveJVMState pjvms(this);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1991 PreserveReexecuteState preexecs(this);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1992 jvms()->set_should_reexecute(true);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1993
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1994 set_control(slow_path);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1995 set_i_o(i_o());
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1996
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1997 uncommon_trap(Deoptimization::Reason_intrinsic,
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1998 Deoptimization::Action_none);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
1999 }
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2000
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2001 set_control(fast_path);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2002 set_result(result);
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2003 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2004
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2005 bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2006 Node* arg1 = argument(0);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2007 Node* arg2 = NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2008
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2009 if (is_increment) {
13019
a57a165b8296 8027353: Exact intrinsics: assert(n != NULL) failed: must not be null
rbackman
parents: 12972
diff changeset
2010 arg2 = intcon(1);
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2011 } else {
13019
a57a165b8296 8027353: Exact intrinsics: assert(n != NULL) failed: must not be null
rbackman
parents: 12972
diff changeset
2012 arg2 = argument(1);
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2013 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2014
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2015 Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2016 inline_math_mathExact(add);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2017 return true;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2018 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2019
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2020 bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2021 Node* arg1 = argument(0); // type long
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2022 // argument(1) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2023 Node* arg2 = NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2024
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2025 if (is_increment) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2026 arg2 = longcon(1);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2027 } else {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2028 arg2 = argument(2); // type long
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2029 // argument(3) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2030 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2031
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2032 Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2033 inline_math_mathExact(add);
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2034 return true;
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2035 }
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2036
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2037 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2038 Node* arg1 = argument(0);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2039 Node* arg2 = NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2040
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2041 if (is_decrement) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2042 arg2 = intcon(1);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2043 } else {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2044 arg2 = argument(1);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2045 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2046
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2047 Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2048 inline_math_mathExact(sub);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2049 return true;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2050 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2051
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2052 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2053 Node* arg1 = argument(0); // type long
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2054 // argument(1) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2055 Node* arg2 = NULL;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2056
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2057 if (is_decrement) {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2058 arg2 = longcon(1);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2059 } else {
13019
a57a165b8296 8027353: Exact intrinsics: assert(n != NULL) failed: must not be null
rbackman
parents: 12972
diff changeset
2060 arg2 = argument(2); // type long
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2061 // argument(3) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2062 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2063
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2064 Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2065 inline_math_mathExact(sub);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2066 return true;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2067 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2068
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2069 bool LibraryCallKit::inline_math_negateExactI() {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2070 Node* arg1 = argument(0);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2071
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2072 Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2073 inline_math_mathExact(neg);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2074 return true;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2075 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2076
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2077 bool LibraryCallKit::inline_math_negateExactL() {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2078 Node* arg1 = argument(0);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2079 // argument(1) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2080
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2081 Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2082 inline_math_mathExact(neg);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2083 return true;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2084 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2085
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2086 bool LibraryCallKit::inline_math_multiplyExactI() {
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2087 Node* arg1 = argument(0);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2088 Node* arg2 = argument(1);
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2089
12972
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2090 Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2091 inline_math_mathExact(mul);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2092 return true;
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2093 }
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2094
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2095 bool LibraryCallKit::inline_math_multiplyExactL() {
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2096 Node* arg1 = argument(0);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2097 // argument(1) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2098 Node* arg2 = argument(2);
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2099 // argument(3) == TOP
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2100
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2101 Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
59e8ad757e19 8026844: Various Math functions needs intrinsification
rbackman
parents: 12966
diff changeset
2102 inline_math_mathExact(mul);
12323
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2103 return true;
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2104 }
c9ccd7b85f20 8024924: Intrinsify java.lang.Math.addExact
rbackman
parents: 12295
diff changeset
2105
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 Node*
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 // These are the candidate return value:
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 Node* xvalue = x0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 Node* yvalue = y0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2111
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 if (xvalue == yvalue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 return xvalue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2115
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 bool want_max = (id == vmIntrinsics::_max);
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 if (txvalue == NULL || tyvalue == NULL) return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 // This is not really necessary, but it is consistent with a
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 // hypothetical MaxINode::Value method:
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 int widen = MAX2(txvalue->_widen, tyvalue->_widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2124
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // %%% This folding logic should (ideally) be in a different place.
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // Some should be inside IfNode, and there to be a more reliable
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 // transformation of ?: style patterns into cmoves. We also want
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // more powerful optimizations around cmove and min/max.
a61af66fc99e Initial load
duke
parents:
diff changeset
2129
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 // Try to find a dominating comparison of these guys.
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 // It can simplify the index computation for Arrays.copyOf
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 // and similar uses of System.arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 // First, compute the normalized version of CmpI(x, y).
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 int cmp_op = Op_CmpI;
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 Node* xkey = xvalue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 Node* ykey = yvalue;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
2137 Node* ideal_cmpxy = _gvn.transform(new(C) CmpINode(xkey, ykey));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 if (ideal_cmpxy->is_Cmp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 // E.g., if we have CmpI(length - offset, count),
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 // it might idealize to CmpI(length, count + offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 cmp_op = ideal_cmpxy->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 xkey = ideal_cmpxy->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 ykey = ideal_cmpxy->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2145
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 // Start by locating any relevant comparisons.
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 Node* start_from = (xkey->outcnt() < ykey->outcnt()) ? xkey : ykey;
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 Node* cmpxy = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 Node* cmpyx = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 for (DUIterator_Fast kmax, k = start_from->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 Node* cmp = start_from->fast_out(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 if (cmp->outcnt() > 0 && // must have prior uses
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 cmp->in(0) == NULL && // must be context-independent
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 cmp->Opcode() == cmp_op) { // right kind of compare
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 if (cmp->in(1) == xkey && cmp->in(2) == ykey) cmpxy = cmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 if (cmp->in(1) == ykey && cmp->in(2) == xkey) cmpyx = cmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2159
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 const int NCMPS = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 Node* cmps[NCMPS] = { cmpxy, cmpyx };
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 int cmpn;
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 for (cmpn = 0; cmpn < NCMPS; cmpn++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 if (cmps[cmpn] != NULL) break; // find a result
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 if (cmpn < NCMPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // Look for a dominating test that tells us the min and max.
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 int depth = 0; // Limit search depth for speed
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 Node* dom = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 for (; dom != NULL; dom = IfNode::up_one_dom(dom, true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 if (++depth >= 100) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 Node* ifproj = dom;
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 if (!ifproj->is_Proj()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 Node* iff = ifproj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 if (!iff->is_If()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 Node* bol = iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 if (!bol->is_Bool()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 Node* cmp = bol->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 if (cmp == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 for (cmpn = 0; cmpn < NCMPS; cmpn++)
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 if (cmps[cmpn] == cmp) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 if (cmpn == NCMPS) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 BoolTest::mask btest = bol->as_Bool()->_test._test;
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 if (ifproj->is_IfFalse()) btest = BoolTest(btest).negate();
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 if (cmp->in(1) == ykey) btest = BoolTest(btest).commute();
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // At this point, we know that 'x btest y' is true.
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 switch (btest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 case BoolTest::eq:
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 // They are proven equal, so we can collapse the min/max.
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // Either value is the answer. Choose the simpler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 if (is_simple_name(yvalue) && !is_simple_name(xvalue))
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 return yvalue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 return xvalue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 case BoolTest::lt: // x < y
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 case BoolTest::le: // x <= y
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 return (want_max ? yvalue : xvalue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 case BoolTest::gt: // x > y
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 case BoolTest::ge: // x >= y
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 return (want_max ? xvalue : yvalue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2203
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 // We failed to find a dominating test.
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // Let's pick a test that might GVN with prior tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 Node* best_bol = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 BoolTest::mask best_btest = BoolTest::illegal;
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 for (cmpn = 0; cmpn < NCMPS; cmpn++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 Node* cmp = cmps[cmpn];
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 if (cmp == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 for (DUIterator_Fast jmax, j = cmp->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 Node* bol = cmp->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 if (!bol->is_Bool()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 BoolTest::mask btest = bol->as_Bool()->_test._test;
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 if (btest == BoolTest::eq || btest == BoolTest::ne) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 if (cmp->in(1) == ykey) btest = BoolTest(btest).commute();
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 if (bol->outcnt() > (best_bol == NULL ? 0 : best_bol->outcnt())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 best_bol = bol->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 best_btest = btest;
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2223
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 Node* answer_if_true = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 Node* answer_if_false = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 switch (best_btest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 if (cmpxy == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 cmpxy = ideal_cmpxy;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
2230 best_bol = _gvn.transform(new(C) BoolNode(cmpxy, BoolTest::lt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // and fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 case BoolTest::lt: // x < y
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 case BoolTest::le: // x <= y
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 answer_if_true = (want_max ? yvalue : xvalue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 answer_if_false = (want_max ? xvalue : yvalue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 case BoolTest::gt: // x > y
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 case BoolTest::ge: // x >= y
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 answer_if_true = (want_max ? xvalue : yvalue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 answer_if_false = (want_max ? yvalue : xvalue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2243
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 jint hi, lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 if (want_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 // We can sharpen the minimum.
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 hi = MAX2(txvalue->_hi, tyvalue->_hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 lo = MAX2(txvalue->_lo, tyvalue->_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // We can sharpen the maximum.
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 hi = MIN2(txvalue->_hi, tyvalue->_hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 lo = MIN2(txvalue->_lo, tyvalue->_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2254
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // Use a flow-free graph structure, to avoid creating excess control edges
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 // which could hinder other optimizations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 // Since Math.min/max is often used with arraycopy, we want
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 // tightly_coupled_allocation to be able to see beyond min/max expressions.
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 Node* cmov = CMoveNode::make(C, NULL, best_bol,
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 answer_if_false, answer_if_true,
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 TypeInt::make(lo, hi, widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2262
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 return _gvn.transform(cmov);
a61af66fc99e Initial load
duke
parents:
diff changeset
2264
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // This is not as desirable as it may seem, since Min and Max
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 // nodes do not have a full set of optimizations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 // And they would interfere, anyway, with 'if' optimizations
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 // and with CMoveI canonical forms.
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 case vmIntrinsics::_min:
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 result_val = _gvn.transform(new (C, 3) MinINode(x,y)); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 case vmIntrinsics::_max:
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 result_val = _gvn.transform(new (C, 3) MaxINode(x,y)); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2280
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 inline int
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 LibraryCallKit::classify_unsafe_addr(Node* &base, Node* &offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 const TypePtr* base_type = TypePtr::NULL_PTR;
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 if (base != NULL) base_type = _gvn.type(base)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 if (base_type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 // Unknown type.
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 return Type::AnyPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 } else if (base_type == TypePtr::NULL_PTR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // Since this is a NULL+long form, we have to switch to a rawptr.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
2290 base = _gvn.transform(new (C) CastX2PNode(offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 offset = MakeConX(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 return Type::RawPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 } else if (base_type->base() == Type::RawPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 return Type::RawPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 } else if (base_type->isa_oopptr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 // Base is never null => always a heap address.
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 if (base_type->ptr() == TypePtr::NotNull) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 return Type::OopPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 // Offset is small => always a heap address.
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 const TypeX* offset_type = _gvn.type(offset)->isa_intptr_t();
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 if (offset_type != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 base_type->offset() == 0 && // (should always be?)
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 offset_type->_lo >= 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 !MacroAssembler::needs_explicit_null_check(offset_type->_hi)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 return Type::OopPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 // Otherwise, it might either be oop+off or NULL+addr.
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 return Type::AnyPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 // No information:
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 return Type::AnyPtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2315
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 inline Node* LibraryCallKit::make_unsafe_address(Node* base, Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 int kind = classify_unsafe_addr(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 if (kind == Type::RawPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 return basic_plus_adr(top(), base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 return basic_plus_adr(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2325 //--------------------------inline_number_methods-----------------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2326 // inline int Integer.numberOfLeadingZeros(int)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2327 // inline int Long.numberOfLeadingZeros(long)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2328 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2329 // inline int Integer.numberOfTrailingZeros(int)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2330 // inline int Long.numberOfTrailingZeros(long)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2331 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2332 // inline int Integer.bitCount(int)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2333 // inline int Long.bitCount(long)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2334 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2335 // inline char Character.reverseBytes(char)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2336 // inline short Short.reverseBytes(short)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2337 // inline int Integer.reverseBytes(int)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2338 // inline long Long.reverseBytes(long)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2339 bool LibraryCallKit::inline_number_methods(vmIntrinsics::ID id) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2340 Node* arg = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2341 Node* n;
775
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 730
diff changeset
2342 switch (id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2343 case vmIntrinsics::_numberOfLeadingZeros_i: n = new (C) CountLeadingZerosINode( arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2344 case vmIntrinsics::_numberOfLeadingZeros_l: n = new (C) CountLeadingZerosLNode( arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2345 case vmIntrinsics::_numberOfTrailingZeros_i: n = new (C) CountTrailingZerosINode(arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2346 case vmIntrinsics::_numberOfTrailingZeros_l: n = new (C) CountTrailingZerosLNode(arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2347 case vmIntrinsics::_bitCount_i: n = new (C) PopCountINode( arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2348 case vmIntrinsics::_bitCount_l: n = new (C) PopCountLNode( arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2349 case vmIntrinsics::_reverseBytes_c: n = new (C) ReverseBytesUSNode(0, arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2350 case vmIntrinsics::_reverseBytes_s: n = new (C) ReverseBytesSNode( 0, arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2351 case vmIntrinsics::_reverseBytes_i: n = new (C) ReverseBytesINode( 0, arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2352 case vmIntrinsics::_reverseBytes_l: n = new (C) ReverseBytesLNode( 0, arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2353 default: fatal_unexpected_iid(id); break;
775
93c14e5562c4 6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents: 730
diff changeset
2354 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2355 set_result(_gvn.transform(n));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2358
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 //----------------------------inline_unsafe_access----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2360
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 const static BasicType T_ADDRESS_HOLDER = T_LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2363 // Helper that guards and inserts a pre-barrier.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2364 void LibraryCallKit::insert_pre_barrier(Node* base_oop, Node* offset,
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2365 Node* pre_val, bool need_mem_bar) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2366 // We could be accessing the referent field of a reference object. If so, when G1
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2367 // is enabled, we need to log the value in the referent field in an SATB buffer.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2368 // This routine performs some compile time filters and generates suitable
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2369 // runtime filters that guard the pre-barrier code.
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2370 // Also add memory barrier for non volatile load from the referent field
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2371 // to prevent commoning of loads across safepoint.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2372 if (!UseG1GC && !need_mem_bar)
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2373 return;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2374
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2375 // Some compile time checks.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2376
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2377 // If offset is a constant, is it java_lang_ref_Reference::_reference_offset?
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2378 const TypeX* otype = offset->find_intptr_t_type();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2379 if (otype != NULL && otype->is_con() &&
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2380 otype->get_con() != java_lang_ref_Reference::referent_offset) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2381 // Constant offset but not the reference_offset so just return
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2382 return;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2383 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2384
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2385 // We only need to generate the runtime guards for instances.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2386 const TypeOopPtr* btype = base_oop->bottom_type()->isa_oopptr();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2387 if (btype != NULL) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2388 if (btype->isa_aryptr()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2389 // Array type so nothing to do
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2390 return;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2391 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2392
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2393 const TypeInstPtr* itype = btype->isa_instptr();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2394 if (itype != NULL) {
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2395 // Can the klass of base_oop be statically determined to be
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2396 // _not_ a sub-class of Reference and _not_ Object?
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2397 ciKlass* klass = itype->klass();
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2398 if ( klass->is_loaded() &&
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2399 !klass->is_subtype_of(env()->Reference_klass()) &&
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2400 !env()->Object_klass()->is_subtype_of(klass)) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2401 return;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2402 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2403 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2404 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2405
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2406 // The compile time filters did not reject base_oop/offset so
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2407 // we need to generate the following runtime filters
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2408 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2409 // if (offset == java_lang_ref_Reference::_reference_offset) {
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2410 // if (instance_of(base, java.lang.ref.Reference)) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2411 // pre_barrier(_, pre_val, ...);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2412 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2413 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2414
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2415 float likely = PROB_LIKELY( 0.999);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2416 float unlikely = PROB_UNLIKELY(0.999);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2417
3255
johnc
parents: 2446 3254
diff changeset
2418 IdealKit ideal(this);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2419 #define __ ideal.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2420
3254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3252
diff changeset
2421 Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2422
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2423 __ if_then(offset, BoolTest::eq, referent_off, unlikely); {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2424 // Update graphKit memory and control from IdealKit.
3255
johnc
parents: 2446 3254
diff changeset
2425 sync_kit(ideal);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2426
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2427 Node* ref_klass_con = makecon(TypeKlassPtr::make(env()->Reference_klass()));
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2428 Node* is_instof = gen_instanceof(base_oop, ref_klass_con);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2429
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2430 // Update IdealKit memory and control from graphKit.
3255
johnc
parents: 2446 3254
diff changeset
2431 __ sync_kit(this);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2432
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2433 Node* one = __ ConI(1);
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2434 // is_instof == 0 if base_oop == NULL
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2435 __ if_then(is_instof, BoolTest::eq, one, unlikely); {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2436
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2437 // Update graphKit from IdeakKit.
3255
johnc
parents: 2446 3254
diff changeset
2438 sync_kit(ideal);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2439
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2440 // Use the pre-barrier to record the value in the referent field
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2441 pre_barrier(false /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2442 __ ctrl(),
3258
edd9b016deb6 7036021: G1: build failure on win64 and linux with hs21 in jdk6 build environment
johnc
parents: 3255
diff changeset
2443 NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */,
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2444 pre_val /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2445 T_OBJECT);
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2446 if (need_mem_bar) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2447 // Add memory barrier to prevent commoning reads from this field
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2448 // across safepoint since GC can change its value.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2449 insert_mem_bar(Op_MemBarCPUOrder);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2450 }
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2451 // Update IdealKit from graphKit.
3255
johnc
parents: 2446 3254
diff changeset
2452 __ sync_kit(this);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2453
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2454 } __ end_if(); // _ref_type != ref_none
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2455 } __ end_if(); // offset == referent_offset
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2456
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2457 // Final sync IdealKit and GraphKit.
3255
johnc
parents: 2446 3254
diff changeset
2458 final_sync(ideal);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2459 #undef __
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2460 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2461
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2462
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 // Interpret Unsafe.fieldOffset cookies correctly:
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2465
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2466 const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2467 // Attempt to infer a sharper value type from the offset and base type.
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2468 ciKlass* sharpened_klass = NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2469
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2470 // See if it is an instance field, with an object type.
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2471 if (alias_type->field() != NULL) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2472 assert(!is_native_ptr, "native pointer op cannot use a java address");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2473 if (alias_type->field()->type()->is_klass()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2474 sharpened_klass = alias_type->field()->type()->as_klass();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2475 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2476 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2477
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2478 // See if it is a narrow oop array.
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2479 if (adr_type->isa_aryptr()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2480 if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2481 const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2482 if (elem_type != NULL) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2483 sharpened_klass = elem_type->klass();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2484 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2485 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2486 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2487
6847
65d07d9ee446 8000263: JSR 292: signature types may appear to be unloaded
twisti
parents: 6804
diff changeset
2488 // The sharpened class might be unloaded if there is no class loader
65d07d9ee446 8000263: JSR 292: signature types may appear to be unloaded
twisti
parents: 6804
diff changeset
2489 // contraint in place.
65d07d9ee446 8000263: JSR 292: signature types may appear to be unloaded
twisti
parents: 6804
diff changeset
2490 if (sharpened_klass != NULL && sharpened_klass->is_loaded()) {
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2491 const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2492
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2493 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
2494 if (C->print_intrinsics() || C->print_inlining()) {
6847
65d07d9ee446 8000263: JSR 292: signature types may appear to be unloaded
twisti
parents: 6804
diff changeset
2495 tty->print(" from base type: "); adr_type->dump();
65d07d9ee446 8000263: JSR 292: signature types may appear to be unloaded
twisti
parents: 6804
diff changeset
2496 tty->print(" sharpened value: "); tjp->dump();
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2497 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2498 #endif
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2499 // Sharpen the value type.
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2500 return tjp;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2501 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2502 return NULL;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2503 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2504
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 if (callee()->is_static()) return false; // caller must have the capability!
a61af66fc99e Initial load
duke
parents:
diff changeset
2507
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 // Check the signatures.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2512 ciSignature* sig = callee()->signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 if (!is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 // Object getObject(Object base, int/long offset), etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 BasicType rtype = sig->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 if (rtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::getAddress_name())
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 rtype = T_ADDRESS; // it is really a C void*
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 assert(rtype == type, "getter must return the expected value");
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 if (!is_native_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 assert(sig->count() == 2, "oop getter has 2 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object");
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct");
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 assert(sig->count() == 1, "native getter has 1 argument");
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 assert(sig->type_at(0)->basic_type() == T_LONG, "getter base is long");
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 // void putObject(Object base, int/long offset, Object x), etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 assert(sig->return_type()->basic_type() == T_VOID, "putter must not return a value");
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 if (!is_native_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 assert(sig->count() == 3, "oop putter has 3 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object");
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct");
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 assert(sig->count() == 2, "native putter has 2 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 assert(sig->type_at(0)->basic_type() == T_LONG, "putter base is long");
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 BasicType vtype = sig->type_at(sig->count()-1)->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 if (vtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::putAddress_name())
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 vtype = T_ADDRESS; // it is really a C void*
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 assert(vtype == type, "putter must accept the expected value");
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2547
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
2549
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2550 Node* receiver = argument(0); // type: oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2551
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 // Build address expression. See the code in inline_unsafe_prefetch.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2553 Node* adr;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2554 Node* heap_base_oop = top();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2555 Node* offset = top();
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2556 Node* val;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2557
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 if (!is_native_ptr) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2559 // The base is either a Java object or a value produced by Unsafe.staticFieldBase
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2560 Node* base = argument(1); // type: oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2562 offset = argument(2); // type: long
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 // to be plain byte offsets, which are also the same as those accepted
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 // by oopDesc::field_base.
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 assert(Unsafe_field_offset_to_byte_offset(11) == 11,
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 // 32-bit machines ignore the high half!
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 heap_base_oop = base;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2572 val = is_store ? argument(4) : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 } else {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2574 Node* ptr = argument(1); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2575 ptr = ConvL2X(ptr); // adjust Java long to machine word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 adr = make_unsafe_address(NULL, ptr);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2577 val = is_store ? argument(3) : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2579
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2581
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 // First guess at the value type.
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 const Type *value_type = Type::get_const_basic_type(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2584
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 // Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM,
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // there was not enough information to nail it down.
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 Compile::AliasType* alias_type = C->alias_type(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
a61af66fc99e Initial load
duke
parents:
diff changeset
2589
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 // We will need memory barriers unless we can determine a unique
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 // alias category for this reference. (Note: If for some reason
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 // the barriers get omitted and the unsafe reference begins to "pollute"
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 // the alias analysis of the rest of the graph, either Compile::can_alias
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 // or Compile::must_alias will throw a diagnostic assert.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 bool need_mem_bar = (alias_type->adr_type() == TypeOopPtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
2596
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2597 // If we are reading the value of the referent field of a Reference
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2598 // object (either by using Unsafe directly or through reflection)
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2599 // then, if G1 is enabled, we need to record the referent in an
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2600 // SATB log buffer using the pre-barrier mechanism.
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2601 // Also we need to add memory barrier to prevent commoning reads
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2602 // from this field across safepoint since GC can change its value.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2603 bool need_read_barrier = !is_native_ptr && !is_store &&
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2604 offset != top() && heap_base_oop != top();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2605
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 if (!is_store && type == T_OBJECT) {
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2607 const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type, is_native_ptr);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2608 if (tjp != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 value_type = tjp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2612
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2613 receiver = null_check(receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 // Heap pointers get a null-check from the interpreter,
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 // as a courtesy. However, this is not guaranteed by Unsafe,
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 // and it is not possible to fully distinguish unintended nulls
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 // from intended ones in this API.
a61af66fc99e Initial load
duke
parents:
diff changeset
2621
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 if (is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 // We need to emit leading and trailing CPU membars (see below) in
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 // addition to memory membars when is_volatile. This is a little
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 // too strong, but avoids the need to insert per-alias-type
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 // volatile membars (for stores; compare Parse::do_put_xxx), which
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
2627 // we cannot do effectively here because we probably only have a
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 // rough approximation of type.
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 need_mem_bar = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 // For Stores, place a memory ordering barrier now.
14452
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2631 if (is_store) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 insert_mem_bar(Op_MemBarRelease);
14452
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2633 } else {
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2634 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2635 insert_mem_bar(Op_MemBarVolatile);
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2636 }
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2637 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2639
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 // Memory barrier to prevent normal and 'unsafe' accesses from
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 // bypassing each other. Happens after null checks, so the
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 // exception paths do not take memory state from the memory barrier,
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 // so there's no problems making a strong assert about mixing users
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 // of safe & unsafe memory. Otherwise fails in a CTW of rt.jar
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 // around 5701, class sun/reflect/UnsafeBooleanFieldAccessorImpl.
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
2647
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 if (!is_store) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2649 Node* p = make_load(control(), adr, value_type, type, adr_type, MemNode::unordered, is_volatile);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2650 // load value
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 case T_INT:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2657 case T_LONG:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 case T_FLOAT:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2659 case T_DOUBLE:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2660 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 case T_OBJECT:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2662 if (need_read_barrier) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2663 insert_pre_barrier(heap_base_oop, offset, p, !(is_volatile || need_mem_bar));
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2664 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 case T_ADDRESS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 // Cast to an int type.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2668 p = _gvn.transform(new (C) CastP2XNode(NULL, p));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 p = ConvX2L(p);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2670 break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2671 default:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2672 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2675 // The load node has the control of the preceding MemBarCPUOrder. All
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2676 // following nodes will have the control of the MemBarCPUOrder inserted at
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2677 // the end of this method. So, pushing the load onto the stack at a later
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2678 // point is fine.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2679 set_result(p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 // place effect of store into memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 val = dstore_rounding(val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 case T_ADDRESS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 // Repackage the long as a pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 val = ConvL2X(val);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
2689 val = _gvn.transform(new (C) CastX2PNode(val));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2692
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2693 MemNode::MemOrd mo = is_volatile ? MemNode::release : MemNode::unordered;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 if (type != T_OBJECT ) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2695 (void) store_to_memory(control(), adr, val, type, adr_type, mo, is_volatile);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 // Possibly an oop being stored to Java heap or native memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 // oop to Java heap.
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2700 (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // We can't tell at compile time if we are storing in the Java heap or outside
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 // of it. So we need to emit code to conditionally do the proper type of
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // store.
a61af66fc99e Initial load
duke
parents:
diff changeset
2705
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2706 IdealKit ideal(this);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2707 #define __ ideal.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 // QQQ who knows what probability is here??
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2709 __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2710 // Sync IdealKit and graphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2711 sync_kit(ideal);
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2712 Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2713 // Update IdealKit memory.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2714 __ sync_kit(this);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2715 } __ else_(); {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2716 __ store(__ ctrl(), adr, val, type, alias_type->index(), mo, is_volatile);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2717 } __ end_if();
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2718 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2719 final_sync(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2720 #undef __
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2724
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 if (is_volatile) {
14452
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2726 if (!is_store) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 insert_mem_bar(Op_MemBarAcquire);
14452
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2728 } else {
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2729 if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2730 insert_mem_bar(Op_MemBarVolatile);
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2731 }
c6d7e7406136 8029101: PPC64 (part 211): ordering of Independent Reads of Independent Writes
goetz
parents: 14439
diff changeset
2732 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2734
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
2736
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2739
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 //----------------------------inline_unsafe_prefetch----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2741
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 bool LibraryCallKit::inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 // Check the signatures.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2747 ciSignature* sig = callee()->signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 // Object getObject(Object base, int/long offset), etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 BasicType rtype = sig->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 if (!is_native_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 assert(sig->count() == 2, "oop prefetch has 2 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 assert(sig->type_at(0)->basic_type() == T_OBJECT, "prefetch base is object");
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 assert(sig->type_at(1)->basic_type() == T_LONG, "prefetcha offset is correct");
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 assert(sig->count() == 1, "native prefetch has 1 argument");
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 assert(sig->type_at(0)->basic_type() == T_LONG, "prefetch base is long");
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2762
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
2764
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2765 const int idx = is_static ? 0 : 1;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2766 if (!is_static) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2767 null_check_receiver();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2768 if (stopped()) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2769 return true;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2770 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2771 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2772
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // Build address expression. See the code in inline_unsafe_access.
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 Node *adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 if (!is_native_ptr) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2776 // The base is either a Java object or a value produced by Unsafe.staticFieldBase
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2777 Node* base = argument(idx + 0); // type: oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2779 Node* offset = argument(idx + 1); // type: long
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 // to be plain byte offsets, which are also the same as those accepted
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 // by oopDesc::field_base.
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 assert(Unsafe_field_offset_to_byte_offset(11) == 11,
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 // 32-bit machines ignore the high half!
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 } else {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2789 Node* ptr = argument(idx + 0); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2790 ptr = ConvL2X(ptr); // adjust Java long to machine word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 adr = make_unsafe_address(NULL, ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2793
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 // Generate the read or write prefetch
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 Node *prefetch;
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 if (is_store) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2797 prefetch = new (C) PrefetchWriteNode(i_o(), adr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2799 prefetch = new (C) PrefetchReadNode(i_o(), adr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 prefetch->init_req(0, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 set_i_o(_gvn.transform(prefetch));
a61af66fc99e Initial load
duke
parents:
diff changeset
2803
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2806
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2807 //----------------------------inline_unsafe_load_store----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2808 // This method serves a couple of different customers (depending on LoadStoreKind):
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2809 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2810 // LS_cmpxchg:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2811 // public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2812 // public final native boolean compareAndSwapInt( Object o, long offset, int expected, int x);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2813 // public final native boolean compareAndSwapLong( Object o, long offset, long expected, long x);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2814 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2815 // LS_xadd:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2816 // public int getAndAddInt( Object o, long offset, int delta)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2817 // public long getAndAddLong(Object o, long offset, long delta)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2818 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2819 // LS_xchg:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2820 // int getAndSet(Object o, long offset, int newValue)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2821 // long getAndSet(Object o, long offset, long newValue)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2822 // Object getAndSet(Object o, long offset, Object newValue)
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2823 //
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2824 bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 // This basic scheme here is the same as inline_unsafe_access, but
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 // differs in enough details that combining them would make the code
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 // overly confusing. (This is a true fact! I originally combined
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 // them, but even I was confused by it!) As much code/comments as
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 // possible are retained from inline_unsafe_access though to make
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
2830 // the correspondences clearer. - dl
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2831
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 if (callee()->is_static()) return false; // caller must have the capability!
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 #ifndef PRODUCT
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2835 BasicType rtype;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 ResourceMark rm;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2838 // Check the signatures.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2839 ciSignature* sig = callee()->signature();
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2840 rtype = sig->return_type()->basic_type();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2841 if (kind == LS_xadd || kind == LS_xchg) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2842 // Check the signatures.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 #ifdef ASSERT
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2844 assert(rtype == type, "get and set must return the expected type");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2845 assert(sig->count() == 3, "get and set has 3 arguments");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2846 assert(sig->type_at(0)->basic_type() == T_OBJECT, "get and set base is object");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2847 assert(sig->type_at(1)->basic_type() == T_LONG, "get and set offset is long");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2848 assert(sig->type_at(2)->basic_type() == type, "get and set must take expected type as new value/delta");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 #endif // ASSERT
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2850 } else if (kind == LS_cmpxchg) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2851 // Check the signatures.
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2852 #ifdef ASSERT
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2853 assert(rtype == T_BOOLEAN, "CAS must return boolean");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2854 assert(sig->count() == 4, "CAS has 4 arguments");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2855 assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2856 assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2857 #endif // ASSERT
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2858 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2859 ShouldNotReachHere();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2860 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2863
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
2865
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2866 // Get arguments:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2867 Node* receiver = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2868 Node* base = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2869 Node* offset = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2870 Node* oldval = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2871 Node* newval = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2872 if (kind == LS_cmpxchg) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2873 const bool two_slot_type = type2size[type] == 2;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2874 receiver = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2875 base = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2876 offset = argument(2); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2877 oldval = argument(4); // type: oop, int, or long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2878 newval = argument(two_slot_type ? 6 : 5); // type: oop, int, or long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2879 } else if (kind == LS_xadd || kind == LS_xchg){
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2880 receiver = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2881 base = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2882 offset = argument(2); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2883 oldval = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2884 newval = argument(4); // type: oop, int, or long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2885 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2886
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2887 // Null check receiver.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2888 receiver = null_check(receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2892
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 // Build field offset expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 // to be plain byte offsets, which are also the same as those accepted
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 // by oopDesc::field_base.
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 // 32-bit machines ignore the high half of long offsets
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 Node* adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2902
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2903 // For CAS, unlike inline_unsafe_access, there seems no point in
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2904 // trying to refine types. Just use the coarse types here.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 const Type *value_type = Type::get_const_basic_type(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 Compile::AliasType* alias_type = C->alias_type(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2908
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2909 if (kind == LS_xchg && type == T_OBJECT) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2910 const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2911 if (tjp != NULL) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2912 value_type = tjp;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2913 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2914 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2915
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 int alias_idx = C->get_alias_index(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2917
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2918 // Memory-model-wise, a LoadStore acts like a little synchronized
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2919 // block, so needs barriers on each side. These don't translate
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2920 // into actual barriers on most machines, but we still need rest of
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 // compiler to respect ordering.
a61af66fc99e Initial load
duke
parents:
diff changeset
2922
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
2925
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // 4984716: MemBars must be inserted before this
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 // memory node in order to avoid a false
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 // dependency which will confuse the scheduler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 Node *mem = memory(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2930
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 // For now, we handle only those cases that actually exist: ints,
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 // longs, and Object. Adding others should be straightforward.
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2933 Node* load_store;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 switch(type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 case T_INT:
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2936 if (kind == LS_xadd) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2937 load_store = _gvn.transform(new (C) GetAndAddINode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2938 } else if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2939 load_store = _gvn.transform(new (C) GetAndSetINode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2940 } else if (kind == LS_cmpxchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2941 load_store = _gvn.transform(new (C) CompareAndSwapINode(control(), mem, adr, newval, oldval));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2942 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2943 ShouldNotReachHere();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2944 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 case T_LONG:
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2947 if (kind == LS_xadd) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2948 load_store = _gvn.transform(new (C) GetAndAddLNode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2949 } else if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2950 load_store = _gvn.transform(new (C) GetAndSetLNode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2951 } else if (kind == LS_cmpxchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2952 load_store = _gvn.transform(new (C) CompareAndSwapLNode(control(), mem, adr, newval, oldval));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2953 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2954 ShouldNotReachHere();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2955 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 case T_OBJECT:
4894
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2958 // Transformation of a value which could be NULL pointer (CastPP #NULL)
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2959 // could be delayed during Parse (for example, in adjust_map_after_if()).
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2960 // Execute transformation here to avoid barrier generation in such case.
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2961 if (_gvn.type(newval) == TypePtr::NULL_PTR)
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2962 newval = _gvn.makecon(TypePtr::NULL_PTR);
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2963
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2964 // Reference stores need a store barrier.
12169
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2965 if (kind == LS_xchg) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2966 // If pre-barrier must execute before the oop store, old value will require do_load here.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2967 if (!can_move_pre_barrier()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2968 pre_barrier(true /* do_load*/,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2969 control(), base, adr, alias_idx, newval, value_type->make_oopptr(),
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2970 NULL /* pre_val*/,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2971 T_OBJECT);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2972 } // Else move pre_barrier to use load_store value, see below.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2973 } else if (kind == LS_cmpxchg) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2974 // Same as for newval above:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2975 if (_gvn.type(oldval) == TypePtr::NULL_PTR) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2976 oldval = _gvn.makecon(TypePtr::NULL_PTR);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2977 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2978 // The only known value which might get overwritten is oldval.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2979 pre_barrier(false /* do_load */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2980 control(), NULL, NULL, max_juint, NULL, NULL,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2981 oldval /* pre_val */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2982 T_OBJECT);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2983 } else {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2984 ShouldNotReachHere();
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2985 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2986
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
2987 #ifdef _LP64
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
2988 if (adr->bottom_type()->is_ptr_to_narrowoop()) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2989 Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2990 if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2991 load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2992 newval_enc, adr_type, value_type->make_narrowoop()));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2993 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2994 assert(kind == LS_cmpxchg, "wrong LoadStore operation");
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2995 Node *oldval_enc = _gvn.transform(new (C) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop()));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2996 load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
2997 newval_enc, oldval_enc));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2998 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
2999 } else
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
3000 #endif
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 174
diff changeset
3001 {
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3002 if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3003 load_store = _gvn.transform(new (C) GetAndSetPNode(control(), mem, adr, newval, adr_type, value_type->is_oopptr()));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3004 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3005 assert(kind == LS_cmpxchg, "wrong LoadStore operation");
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3006 load_store = _gvn.transform(new (C) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3007 }
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 174
diff changeset
3008 }
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3009 post_barrier(control(), load_store, base, adr, alias_idx, newval, T_OBJECT, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3012 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3015
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3016 // SCMemProjNodes represent the memory state of a LoadStore. Their
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3017 // main role is to prevent LoadStore nodes from being optimized away
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3018 // when their results aren't used.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3019 Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 set_memory(proj, alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3021
12169
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3022 if (type == T_OBJECT && kind == LS_xchg) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3023 #ifdef _LP64
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3024 if (adr->bottom_type()->is_ptr_to_narrowoop()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3025 load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type()));
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3026 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3027 #endif
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3028 if (can_move_pre_barrier()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3029 // Don't need to load pre_val. The old value is returned by load_store.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3030 // The pre_barrier can execute after the xchg as long as no safepoint
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3031 // gets inserted between them.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3032 pre_barrier(false /* do_load */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3033 control(), NULL, NULL, max_juint, NULL, NULL,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3034 load_store /* pre_val */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3035 T_OBJECT);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3036 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3037 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3038
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 // Add the trailing membar surrounding the access
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 insert_mem_bar(Op_MemBarAcquire);
a61af66fc99e Initial load
duke
parents:
diff changeset
3042
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3043 assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match");
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3044 set_result(load_store);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3047
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3048 //----------------------------inline_unsafe_ordered_store----------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3049 // public native void sun.misc.Unsafe.putOrderedObject(Object o, long offset, Object x);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3050 // public native void sun.misc.Unsafe.putOrderedInt(Object o, long offset, int x);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3051 // public native void sun.misc.Unsafe.putOrderedLong(Object o, long offset, long x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 // This is another variant of inline_unsafe_access, differing in
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 // that it always issues store-store ("release") barrier and ensures
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 // store-atomicity (which only matters for "long").
a61af66fc99e Initial load
duke
parents:
diff changeset
3056
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 if (callee()->is_static()) return false; // caller must have the capability!
a61af66fc99e Initial load
duke
parents:
diff changeset
3058
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // Check the signatures.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3063 ciSignature* sig = callee()->signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 BasicType rtype = sig->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 assert(rtype == T_VOID, "must return void");
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 assert(sig->count() == 3, "has 3 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 assert(sig->type_at(0)->basic_type() == T_OBJECT, "base is object");
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 assert(sig->type_at(1)->basic_type() == T_LONG, "offset is long");
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3073
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
3075
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3076 // Get arguments:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3077 Node* receiver = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3078 Node* base = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3079 Node* offset = argument(2); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3080 Node* val = argument(4); // type: oop, int, or long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3081
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3082 // Null check receiver.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3083 receiver = null_check(receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3087
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 // Build field offset expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // 32-bit machines ignore the high half of long offsets
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 Node* adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 const Type *value_type = Type::get_const_basic_type(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 Compile::AliasType* alias_type = C->alias_type(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3096
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 // Ensure that the store is atomic for longs:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3100 const bool require_atomic_access = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 Node* store;
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 if (type == T_OBJECT) // reference stores need a store barrier.
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3103 store = store_oop_to_unknown(control(), base, adr, adr_type, val, type, MemNode::release);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 else {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3105 store = store_to_memory(control(), adr, val, type, adr_type, MemNode::release, require_atomic_access);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3110
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3111 bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3112 // Regardless of form, don't allow previous ld/st to move down,
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3113 // then issue acquire, release, or volatile mem_bar.
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3114 insert_mem_bar(Op_MemBarCPUOrder);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3115 switch(id) {
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3116 case vmIntrinsics::_loadFence:
14439
50fdb38839eb 8028515: PPPC64 (part 113.2): opto: Introduce LoadFence/StoreFence.
goetz
parents: 14429
diff changeset
3117 insert_mem_bar(Op_LoadFence);
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3118 return true;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3119 case vmIntrinsics::_storeFence:
14439
50fdb38839eb 8028515: PPPC64 (part 113.2): opto: Introduce LoadFence/StoreFence.
goetz
parents: 14429
diff changeset
3120 insert_mem_bar(Op_StoreFence);
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3121 return true;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3122 case vmIntrinsics::_fullFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3123 insert_mem_bar(Op_MemBarVolatile);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3124 return true;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3125 default:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3126 fatal_unexpected_iid(id);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3127 return false;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3128 }
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3129 }
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3130
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3131 bool LibraryCallKit::klass_needs_init_guard(Node* kls) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3132 if (!kls->is_Con()) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3133 return true;
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3134 }
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3135 const TypeKlassPtr* klsptr = kls->bottom_type()->isa_klassptr();
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3136 if (klsptr == NULL) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3137 return true;
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3138 }
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3139 ciInstanceKlass* ik = klsptr->klass()->as_instance_klass();
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3140 // don't need a guard for a klass that is already initialized
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3141 return !ik->is_initialized();
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3142 }
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3143
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3144 //----------------------------inline_unsafe_allocate---------------------------
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3145 // public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 bool LibraryCallKit::inline_unsafe_allocate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 if (callee()->is_static()) return false; // caller must have the capability!
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3148
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3149 null_check_receiver(); // null-check, then ignore
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3150 Node* cls = null_check(argument(1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3152
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3153 Node* kls = load_klass_from_mirror(cls, false, NULL, 0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3154 kls = null_check(kls);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 if (stopped()) return true; // argument was like int.class
a61af66fc99e Initial load
duke
parents:
diff changeset
3156
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3157 Node* test = NULL;
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3158 if (LibraryCallKit::klass_needs_init_guard(kls)) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3159 // Note: The argument might still be an illegal value like
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3160 // Serializable.class or Object[].class. The runtime will handle it.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3161 // But we must make an explicit check for initialization.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3162 Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3163 // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3164 // can generate code to load it as unsigned byte.
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3165 Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered);
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3166 Node* bits = intcon(InstanceKlass::fully_initialized);
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3167 test = _gvn.transform(new (C) SubINode(inst, bits));
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3168 // The 'test' is non-zero if we need to take a slow path.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3169 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3170
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 Node* obj = new_instance(kls, test);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3172 set_result(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3175
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3176 #ifdef TRACE_HAVE_INTRINSICS
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3177 /*
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3178 * oop -> myklass
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3179 * myklass->trace_id |= USED
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3180 * return myklass->trace_id & ~0x3
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3181 */
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3182 bool LibraryCallKit::inline_native_classID() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3183 null_check_receiver(); // null-check, then ignore
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3184 Node* cls = null_check(argument(1), T_OBJECT);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3185 Node* kls = load_klass_from_mirror(cls, false, NULL, 0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3186 kls = null_check(kls, T_OBJECT);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3187 ByteSize offset = TRACE_ID_OFFSET;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3188 Node* insp = basic_plus_adr(kls, in_bytes(offset));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3189 Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3190 Node* bits = longcon(~0x03l); // ignore bit 0 & 1
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3191 Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits));
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3192 Node* clsused = longcon(0x01l); // set the class bit
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3193 Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused));
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3194
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3195 const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3196 store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3197 set_result(andl);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3198 return true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3199 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3200
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3201 bool LibraryCallKit::inline_native_threadID() {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3202 Node* tls_ptr = NULL;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3203 Node* cur_thr = generate_current_thread(tls_ptr);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3204 Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3205 Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3206 p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::thread_id_offset()));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3207
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3208 Node* threadid = NULL;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3209 size_t thread_id_size = OSThread::thread_id_size();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3210 if (thread_id_size == (size_t) BytesPerLong) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3211 threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG, MemNode::unordered));
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3212 } else if (thread_id_size == (size_t) BytesPerInt) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3213 threadid = make_load(control(), p, TypeInt::INT, T_INT, MemNode::unordered);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3214 } else {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3215 ShouldNotReachHere();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3216 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3217 set_result(threadid);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3218 return true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3219 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3220 #endif
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3221
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 //------------------------inline_native_time_funcs--------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 // inline code for System.currentTimeMillis() and System.nanoTime()
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 // these have the same type and signature
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3225 bool LibraryCallKit::inline_native_time_funcs(address funcAddr, const char* funcName) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3226 const TypeFunc* tf = OptoRuntime::void_long_Type();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 const TypePtr* no_memory_effects = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 Node* time = make_runtime_call(RC_LEAF, tf, funcAddr, funcName, no_memory_effects);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3229 Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 #ifdef ASSERT
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3231 Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 assert(value_top == top(), "second value must be top");
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 #endif
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3234 set_result(value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3237
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 //------------------------inline_native_currentThread------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 bool LibraryCallKit::inline_native_currentThread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 Node* junk = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3241 set_result(generate_current_thread(junk));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3244
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 //------------------------inline_native_isInterrupted------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 bool LibraryCallKit::inline_native_isInterrupted() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 // Add a fast path to t.isInterrupted(clear_int):
14649
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3249 // (t == Thread.current() &&
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3250 // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 // So, in the common case that the interrupt bit is false,
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 // we avoid making a call into the VM. Even if the interrupt bit
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 // is true, if the clear_int argument is false, we avoid the VM call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 // However, if the receiver is not currentThread, we must call the VM,
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 // because there must be some locking done around the operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3257
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 // We only go to the fast case code if we pass two guards.
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 // Paths which do not pass are accumulated in the slow_region.
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3260
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3261 enum {
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3262 no_int_result_path = 1, // t == Thread.current() && !TLS._osthread._interrupted
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3263 no_clear_result_path = 2, // t == Thread.current() && TLS._osthread._interrupted && !clear_int
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3264 slow_result_path = 3, // slow path: t.isInterrupted(clear_int)
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3265 PATH_LIMIT
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3266 };
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3267
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3268 // Ensure that it's not possible to move the load of TLS._osthread._interrupted flag
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3269 // out of the function.
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3270 insert_mem_bar(Op_MemBarCPUOrder);
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3271
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3272 RegionNode* result_rgn = new (C) RegionNode(PATH_LIMIT);
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3273 PhiNode* result_val = new (C) PhiNode(result_rgn, TypeInt::BOOL);
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3274
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3275 RegionNode* slow_region = new (C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3277
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 // (a) Receiving thread must be the current thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 Node* rec_thr = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 Node* tls_ptr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 Node* cur_thr = generate_current_thread(tls_ptr);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3282 Node* cmp_thr = _gvn.transform(new (C) CmpPNode(cur_thr, rec_thr));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3283 Node* bol_thr = _gvn.transform(new (C) BoolNode(cmp_thr, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3284
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3285 generate_slow_guard(bol_thr, slow_region);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3286
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 // (b) Interrupt bit on TLS must be false.
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3289 Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3291
787
aabd393cf1ee 6772683: Thread.isInterrupted() fails to return true on multiprocessor PC
kvn
parents: 775
diff changeset
3292 // Set the control input on the field _interrupted read to prevent it floating up.
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3293 Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3294 Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3295 Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3296
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
3298
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 // First fast path: if (!TLS._interrupted) return false;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3300 Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 result_rgn->init_req(no_int_result_path, false_bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 result_val->init_req(no_int_result_path, intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3303
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 // drop through to next case
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3305 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3306
14649
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3307 #ifndef TARGET_OS_FAMILY_windows
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 Node* clr_arg = argument(1);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3310 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3311 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
3313
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 // Second fast path: ... else if (!clear_int) return true;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3315 Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 result_rgn->init_req(no_clear_result_path, false_arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 result_val->init_req(no_clear_result_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3318
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 // drop through to next case
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3320 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
14649
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3321 #else
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3322 // To return true on Windows you must read the _interrupted field
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3323 // and check the the event state i.e. take the slow path.
f6301b007a16 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 14463
diff changeset
3324 #endif // TARGET_OS_FAMILY_windows
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3325
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 // (d) Otherwise, go to the slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 slow_region->add_req(control());
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3328 set_control( _gvn.transform(slow_region));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3329
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 // There is no slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 result_rgn->init_req(slow_result_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 result_val->init_req(slow_result_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 // non-virtual because it is a private non-static
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_isInterrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
3337
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 Node* slow_val = set_results_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 // this->control() comes from set_results_for_java_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3340
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 Node* fast_io = slow_call->in(TypeFunc::I_O);
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 Node* fast_mem = slow_call->in(TypeFunc::Memory);
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3343
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 // These two phis are pre-filled with copies of of the fast IO and Memory
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3345 PhiNode* result_mem = PhiNode::make(result_rgn, fast_mem, Type::MEMORY, TypePtr::BOTTOM);
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3346 PhiNode* result_io = PhiNode::make(result_rgn, fast_io, Type::ABIO);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3347
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 result_rgn->init_req(slow_result_path, control());
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3349 result_io ->init_req(slow_result_path, i_o());
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3350 result_mem->init_req(slow_result_path, reset_memory());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 result_val->init_req(slow_result_path, slow_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
3352
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3353 set_all_memory(_gvn.transform(result_mem));
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3354 set_i_o( _gvn.transform(result_io));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3356
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 C->set_has_split_ifs(true); // Has chance for split-if optimization
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3358 set_result(result_rgn, result_val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3361
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 //---------------------------load_mirror_from_klass----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 // Given a klass oop, load its java mirror (a java.lang.Class oop).
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3365 Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3366 return make_load(NULL, p, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3368
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 //-----------------------load_klass_from_mirror_common-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 // Given a java mirror (a java.lang.Class oop), load its corresponding klass oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 // Test the klass oop for null (signifying a primitive Class like Integer.TYPE),
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 // and branch to the given path on the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 // If never_see_null, take an uncommon trap on null, so we can optimistically
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 // compile for the non-null case.
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 // If the region is NULL, force never_see_null = true.
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror,
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 bool never_see_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 int null_path,
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 if (region == NULL) never_see_null = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 Node* p = basic_plus_adr(mirror, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3384 Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 kls = null_check_oop(kls, &null_ctl, never_see_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 if (region != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 // Set region->in(null_path) if the mirror is a primitive (e.g, int.class).
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 region->init_req(null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 assert(null_ctl == top(), "no loose ends");
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 return kls;
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3395
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 //--------------------(inline_native_Class_query helpers)---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 // Use this for JVM_ACC_INTERFACE, JVM_ACC_IS_CLONEABLE, JVM_ACC_HAS_FINALIZER.
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 // Fall through if (mods & mask) == bits, take the guard otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 // Branch around if the given klass has the given modifier bit set.
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 // Like generate_guard, adds a new path onto the region.
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3402 Node* modp = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3403 Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 Node* mask = intcon(modifier_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 Node* bits = intcon(modifier_bits);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3406 Node* mbit = _gvn.transform(new (C) AndINode(mods, mask));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3407 Node* cmp = _gvn.transform(new (C) CmpINode(mbit, bits));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3408 Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 return generate_fair_guard(bol, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 return generate_access_flags_guard(kls, JVM_ACC_INTERFACE, 0, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3414
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 //-------------------------inline_native_Class_query-------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 const Type* return_type = TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 Node* prim_return_value = top(); // what happens if it's a primitive class?
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 bool expect_prim = false; // most of these guys expect to work on refs
a61af66fc99e Initial load
duke
parents:
diff changeset
3421
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 enum { _normal_path = 1, _prim_path = 2, PATH_LIMIT };
a61af66fc99e Initial load
duke
parents:
diff changeset
3423
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3424 Node* mirror = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3425 Node* obj = top();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3426
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 case vmIntrinsics::_isInstance:
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 // nothing is an instance of a primitive type
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 prim_return_value = intcon(0);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3431 obj = argument(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 case vmIntrinsics::_getModifiers:
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line");
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin);
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 case vmIntrinsics::_isInterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 prim_return_value = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 case vmIntrinsics::_isArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 prim_return_value = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 expect_prim = true; // cf. ObjectStreamClass.getClassSignature
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 case vmIntrinsics::_isPrimitive:
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 prim_return_value = intcon(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 expect_prim = true; // obviously
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 case vmIntrinsics::_getSuperclass:
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 prim_return_value = null();
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 case vmIntrinsics::_getComponentType:
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 prim_return_value = null();
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 case vmIntrinsics::_getClassAccessFlags:
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 return_type = TypeInt::INT; // not bool! 6297094
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3462 fatal_unexpected_iid(id);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3463 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3465
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 if (mirror_con == NULL) return false; // cannot happen?
a61af66fc99e Initial load
duke
parents:
diff changeset
3468
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
3470 if (C->print_intrinsics() || C->print_inlining()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 ciType* k = mirror_con->java_mirror_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 if (k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3474 k->print_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3479
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 // Null-check the mirror, and the mirror's klass ptr (in case it is a primitive).
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3481 RegionNode* region = new (C) RegionNode(PATH_LIMIT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 record_for_igvn(region);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3483 PhiNode* phi = new (C) PhiNode(region, return_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3484
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 // The mirror will never be null of Reflection.getClassAccessFlags, however
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 // if it is. See bug 4774291.
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 // For Reflection.getClassAccessFlags(), the null check occurs in
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 // the wrong place; see inline_unsafe_access(), above, for a similar
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 // situation.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3492 mirror = null_check(mirror);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 // If mirror or obj is dead, only null-path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3495
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 if (expect_prim) never_see_null = false; // expect nulls (meaning prims)
a61af66fc99e Initial load
duke
parents:
diff changeset
3497
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 // Now load the mirror's klass metaobject, and null-check it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 // Side-effects region with the control path if the klass is null.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3500 Node* kls = load_klass_from_mirror(mirror, never_see_null, region, _prim_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 // If kls is null, we have a primitive mirror.
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 phi->init_req(_prim_path, prim_return_value);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3503 if (stopped()) { set_result(region, phi); return true; }
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3504 bool safe_for_replace = (region->in(_prim_path) == top());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3505
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 Node* p; // handy temp
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 Node* null_ctl;
a61af66fc99e Initial load
duke
parents:
diff changeset
3508
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 // Now that we have the non-null klass, we can perform the real query.
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 // For constant classes, the query will constant-fold in LoadNode::Value.
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 Node* query_value = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 case vmIntrinsics::_isInstance:
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 // nothing is an instance of a primitive type
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3515 query_value = gen_instanceof(obj, kls, safe_for_replace);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3517
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 case vmIntrinsics::_getModifiers:
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3519 p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3520 query_value = make_load(NULL, p, TypeInt::INT, T_INT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3522
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 case vmIntrinsics::_isInterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 // (To verify this code sequence, check the asserts in JVM_IsInterface.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 if (generate_interface_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 // A guard was added. If the guard is taken, it was an interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 phi->add_req(intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 // If we fall through, it's a plain class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 query_value = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3531
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 case vmIntrinsics::_isArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 // (To verify this code sequence, check the asserts in JVM_IsArrayClass.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 if (generate_array_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 // A guard was added. If the guard is taken, it was an array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 phi->add_req(intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 // If we fall through, it's a plain class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 query_value = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3540
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 case vmIntrinsics::_isPrimitive:
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 query_value = intcon(0); // "normal" path produces false
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3544
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 case vmIntrinsics::_getSuperclass:
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 // The rules here are somewhat unfortunate, but we can still do better
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 // with random logic than with a JNI call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 // Interfaces store null or Object as _super, but must report null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 // Arrays store an intermediate super as _super, but must report Object.
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 // Other types can report the actual _super.
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 // (To verify this code sequence, check the asserts in JVM_IsInterface.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 if (generate_interface_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 // A guard was added. If the guard is taken, it was an interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 phi->add_req(null());
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 if (generate_array_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 // A guard was added. If the guard is taken, it was an array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 // If we fall through, it's a plain class. Get its _super.
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3559 p = basic_plus_adr(kls, in_bytes(Klass::super_offset()));
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3560 kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 kls = null_check_oop(kls, &null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 if (null_ctl != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 // If the guard is taken, Object.superClass is null (both klass and mirror).
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 region->add_req(null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 phi ->add_req(null());
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 query_value = load_mirror_from_klass(kls);
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3572
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 case vmIntrinsics::_getComponentType:
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 if (generate_array_guard(kls, region) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 // Be sure to pin the oop load to the guard edge just created:
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 Node* is_array_ctrl = region->in(region->req()-1);
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6804
diff changeset
3577 Node* cma = basic_plus_adr(kls, in_bytes(ArrayKlass::component_mirror_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3578 Node* cmo = make_load(is_array_ctrl, cma, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 phi->add_req(cmo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 query_value = null(); // non-array case is null
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3583
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 case vmIntrinsics::_getClassAccessFlags:
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3585 p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3586 query_value = make_load(NULL, p, TypeInt::INT, T_INT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3588
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3590 fatal_unexpected_iid(id);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3591 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3593
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 // Fall-through is the normal case of a query to a real class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 phi->init_req(1, query_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 region->init_req(1, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3597
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 C->set_has_split_ifs(true); // Has chance for split-if optimization
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3599 set_result(region, phi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3602
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 //--------------------------inline_native_subtype_check------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 // This intrinsic takes the JNI calls out of the heart of
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 // UnsafeFieldAccessorImpl.set, which improves Field.set, readObject, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 bool LibraryCallKit::inline_native_subtype_check() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 // Pull both arguments off the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 Node* args[2]; // two java.lang.Class mirrors: superc, subc
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 args[0] = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 args[1] = argument(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 Node* klasses[2]; // corresponding Klasses: superk, subk
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 klasses[0] = klasses[1] = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3613
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 // A full decision tree on {superc is prim, subc is prim}:
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 _prim_0_path = 1, // {P,N} => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 // {P,P} & superc!=subc => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 _prim_same_path, // {P,P} & superc==subc => true
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 _prim_1_path, // {N,P} => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 _ref_subtype_path, // {N,N} & subtype check wins => true
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 _both_ref_path, // {N,N} & subtype check loses => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 PATH_LIMIT
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3624
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3625 RegionNode* region = new (C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3626 Node* phi = new (C) PhiNode(region, TypeInt::BOOL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3628
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 int class_klass_offset = java_lang_Class::klass_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3632
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 // First null-check both mirrors and load each mirror's klass metaobject.
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 int which_arg;
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 for (which_arg = 0; which_arg <= 1; which_arg++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 Node* arg = args[which_arg];
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3637 arg = null_check(arg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 if (stopped()) break;
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
3639 args[which_arg] = arg;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3640
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 Node* p = basic_plus_adr(arg, class_klass_offset);
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
3642 Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 klasses[which_arg] = _gvn.transform(kls);
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3645
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 // Having loaded both klasses, test each for null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 for (which_arg = 0; which_arg <= 1; which_arg++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 Node* kls = klasses[which_arg];
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 kls = null_check_oop(kls, &null_ctl, never_see_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 int prim_path = (which_arg == 0 ? _prim_0_path : _prim_1_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 region->init_req(prim_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 if (stopped()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 klasses[which_arg] = kls;
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3657
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 // now we have two reference types, in klasses[0..1]
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 Node* subk = klasses[1]; // the argument to isAssignableFrom
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 Node* superk = klasses[0]; // the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 region->set_req(_both_ref_path, gen_subtype_check(subk, superk));
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 // now we have a successful reference subtype check
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 region->set_req(_ref_subtype_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3666
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // If both operands are primitive (both klasses null), then
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // we must return true when they are identical primitives.
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // It is convenient to test this after the first null klass check.
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 set_control(region->in(_prim_0_path)); // go back to first null check
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 // Since superc is primitive, make a guard for the superc==subc case.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3673 Node* cmp_eq = _gvn.transform(new (C) CmpPNode(args[0], args[1]));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3674 Node* bol_eq = _gvn.transform(new (C) BoolNode(cmp_eq, BoolTest::eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 generate_guard(bol_eq, region, PROB_FAIR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 if (region->req() == PATH_LIMIT+1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // A guard was added. If the added guard is taken, superc==subc.
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 region->swap_edges(PATH_LIMIT, _prim_same_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 region->del_req(PATH_LIMIT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 region->set_req(_prim_0_path, control()); // Not equal after all.
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3683
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // these are the only paths that produce 'true':
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 phi->set_req(_prim_same_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 phi->set_req(_ref_subtype_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3687
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // pull together the cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 assert(region->req() == PATH_LIMIT, "sane region");
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 for (uint i = 1; i < region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 Node* ctl = region->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 if (ctl == NULL || ctl == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 region->set_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 phi ->set_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 } else if (phi->in(i) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 phi->set_req(i, intcon(0)); // all other paths produce 'false'
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3699
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 set_control(_gvn.transform(region));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3701 set_result(_gvn.transform(phi));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3704
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 //---------------------generate_array_guard_common------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 bool obj_array, bool not_array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // If obj_array/non_array==false/false:
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 // Branch around if the given klass is in fact an array (either obj or prim).
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 // If obj_array/non_array==false/true:
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 // Branch around if the given klass is not an array klass of any kind.
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 // If obj_array/non_array==true/true:
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 // Branch around if the kls is not an oop array (kls is int[], String, etc.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 // If obj_array/non_array==true/false:
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 // Branch around if the kls is an oop array (Object[] or subtype)
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 // Like generate_guard, adds a new path onto the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 jint layout_con = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 Node* layout_val = get_layout_helper(kls, layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 if (layout_val == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 bool query = (obj_array
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 ? Klass::layout_helper_is_objArray(layout_con)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3723 : Klass::layout_helper_is_array(layout_con));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 if (query == not_array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 return NULL; // never a branch
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 } else { // always a branch
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 Node* always_branch = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 if (region != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 region->add_req(always_branch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 return always_branch;
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 // Now test the correct condition.
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 jint nval = (obj_array
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 ? ((jint)Klass::_lh_array_tag_type_value
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 << Klass::_lh_array_tag_shift)
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 : Klass::_lh_neutral_value);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3739 Node* cmp = _gvn.transform(new(C) CmpINode(layout_val, intcon(nval)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 // invert the test if we are looking for a non-array
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 if (not_array) btest = BoolTest(btest).negate();
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3743 Node* bol = _gvn.transform(new(C) BoolNode(cmp, btest));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 return generate_fair_guard(bol, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3746
a61af66fc99e Initial load
duke
parents:
diff changeset
3747
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 //-----------------------inline_native_newArray--------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3749 // private static native Object java.lang.reflect.newArray(Class<?> componentType, int length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 bool LibraryCallKit::inline_native_newArray() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 Node* mirror = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 Node* count_val = argument(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3753
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3754 mirror = null_check(mirror);
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
3755 // If mirror or obj is dead, only null-path is taken.
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
3756 if (stopped()) return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3757
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3759 RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3760 PhiNode* result_val = new(C) PhiNode(result_reg,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3761 TypeInstPtr::NOTNULL);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3762 PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3763 PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3764 TypePtr::BOTTOM);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3765
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 result_reg, _slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 Node* normal_ctl = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 Node* no_array_ctl = result_reg->in(_slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3771
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 // Generate code for the slow case. We make a call to newArray().
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 set_control(no_array_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 // Either the input type is void.class, or else the
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 // array klass has not yet been cached. Either the
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 // ensuing call will throw an exception, or else it
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 // will cache the array klass for next time.
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 CallJavaNode* slow_call = generate_method_call_static(vmIntrinsics::_newArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 Node* slow_result = set_results_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 // this->control() comes from set_results_for_java_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 result_reg->set_req(_slow_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 result_val->set_req(_slow_path, slow_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 result_io ->set_req(_slow_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 result_mem->set_req(_slow_path, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3788
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 set_control(normal_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 // Normal case: The array type has been cached in the java.lang.Class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 // The following call works fine even if the array type is polymorphic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 // It could be a dynamic mix of int[], boolean[], Object[], etc.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3794 Node* obj = new_array(klass_node, count_val, 0); // no arguments to push
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 result_reg->init_req(_normal_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 result_val->init_req(_normal_path, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 result_io ->init_req(_normal_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 result_mem->init_req(_normal_path, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3800
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 // Return the combined state.
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 set_i_o( _gvn.transform(result_io) );
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3803 set_all_memory( _gvn.transform(result_mem));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3804
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 C->set_has_split_ifs(true); // Has chance for split-if optimization
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3806 set_result(result_reg, result_val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3809
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 //----------------------inline_native_getLength--------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3811 // public static native int java.lang.reflect.Array.getLength(Object array);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 bool LibraryCallKit::inline_native_getLength() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3814
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3815 Node* array = null_check(argument(0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 // If array is dead, only null-path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3818
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 // Deoptimize if it is a non-array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 Node* non_array = generate_non_array_guard(load_object_klass(array), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3821
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 if (non_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 set_control(non_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 uncommon_trap(Deoptimization::Reason_intrinsic,
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 Deoptimization::Action_maybe_recompile);
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3828
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 // If control is dead, only non-array-path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3831
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 // The works fine even if the array type is polymorphic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 // It could be a dynamic mix of int[], boolean[], Object[], etc.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3834 Node* result = load_array_length(array);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3835
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3836 C->set_has_split_ifs(true); // Has chance for split-if optimization
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3837 set_result(result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3840
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 //------------------------inline_array_copyOf----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3842 // public static <T,U> T[] java.util.Arrays.copyOf( U[] original, int newLength, Class<? extends T[]> newType);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3843 // public static <T,U> T[] java.util.Arrays.copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3846
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3847 // Get the arguments.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 Node* original = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 Node* start = is_copyOfRange? argument(1): intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 Node* end = is_copyOfRange? argument(2): argument(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 Node* array_type_mirror = is_copyOfRange? argument(3): argument(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3852
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3853 Node* newcopy;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3854
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3855 // Set the original stack and the reexecute bit for the interpreter to reexecute
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3856 // the bytecode that invokes Arrays.copyOf if deoptimization happens.
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3857 { PreserveReexecuteState preexecs(this);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3858 jvms()->set_should_reexecute(true);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3859
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3860 array_type_mirror = null_check(array_type_mirror);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3861 original = null_check(original);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3862
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3863 // Check if a null path was taken unconditionally.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3864 if (stopped()) return true;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3865
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3866 Node* orig_length = load_array_length(original);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3867
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3868 Node* klass_node = load_klass_from_mirror(array_type_mirror, false, NULL, 0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3869 klass_node = null_check(klass_node);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3870
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3871 RegionNode* bailout = new (C) RegionNode(1);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3872 record_for_igvn(bailout);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3873
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3874 // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3875 // Bail out if that is so.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3876 Node* not_objArray = generate_non_objArray_guard(klass_node, bailout);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3877 if (not_objArray != NULL) {
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3878 // Improve the klass node's type from the new optimistic assumption:
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3879 ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3880 const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3881 Node* cast = new (C) CastPPNode(klass_node, akls);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3882 cast->init_req(0, control());
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3883 klass_node = _gvn.transform(cast);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3884 }
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3885
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3886 // Bail out if either start or end is negative.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3887 generate_negative_guard(start, bailout, &start);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3888 generate_negative_guard(end, bailout, &end);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3889
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3890 Node* length = end;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3891 if (_gvn.type(start) != TypeInt::ZERO) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3892 length = _gvn.transform(new (C) SubINode(end, start));
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3893 }
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3894
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3895 // Bail out if length is negative.
6180
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3896 // Without this the new_array would throw
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3897 // NegativeArraySizeException but IllegalArgumentException is what
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3898 // should be thrown
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3899 generate_negative_guard(length, bailout, &length);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3900
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3901 if (bailout->req() > 1) {
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3902 PreserveJVMState pjvms(this);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3903 set_control(_gvn.transform(bailout));
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3904 uncommon_trap(Deoptimization::Reason_intrinsic,
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3905 Deoptimization::Action_maybe_recompile);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3906 }
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3907
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3908 if (!stopped()) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3909 // How many elements will we copy from the original?
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3910 // The answer is MinI(orig_length - start, length).
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3911 Node* orig_tail = _gvn.transform(new (C) SubINode(orig_length, start));
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3912 Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3913
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3914 newcopy = new_array(klass_node, length, 0); // no argments to push
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3915
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3916 // Generate a direct call to the right arraycopy function(s).
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3917 // We know the copy is disjoint but we might not know if the
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3918 // oop stores need checking.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3919 // Extreme case: Arrays.copyOf((Integer[])x, 10, String[].class).
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3920 // This will fail a store-check if x contains any non-nulls.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3921 bool disjoint_bases = true;
6180
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3922 // if start > orig_length then the length of the copy may be
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3923 // negative.
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3924 bool length_never_negative = !is_copyOfRange;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3925 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3926 original, start, newcopy, intcon(0), moved,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3927 disjoint_bases, length_never_negative);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3928 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3929 } // original reexecute is set back here
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3930
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 C->set_has_split_ifs(true); // Has chance for split-if optimization
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3932 if (!stopped()) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3933 set_result(newcopy);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3934 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3937
a61af66fc99e Initial load
duke
parents:
diff changeset
3938
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 //----------------------generate_virtual_guard---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 // Helper for hashCode and clone. Peeks inside the vtable to avoid a call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 RegionNode* slow_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 ciMethod* method = callee();
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 int vtable_index = method->vtable_index();
12264
b2e698d2276c 8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents: 12190
diff changeset
3945 assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
b2e698d2276c 8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents: 12190
diff changeset
3946 err_msg_res("bad index %d", vtable_index));
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3947 // Get the Method* out of the appropriate vtable entry.
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3948 int entry_offset = (InstanceKlass::vtable_start_offset() +
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 vtable_index*vtableEntry::size()) * wordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 vtableEntry::method_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 Node* entry_addr = basic_plus_adr(obj_klass, entry_offset);
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
3952 Node* target_call = make_load(NULL, entry_addr, TypePtr::NOTNULL, T_ADDRESS, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3953
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 // Compare the target method with the expected method (e.g., Object.hashCode).
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3955 const TypePtr* native_call_addr = TypeMetadataPtr::make(method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3956
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 Node* native_call = makecon(native_call_addr);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3958 Node* chk_native = _gvn.transform(new(C) CmpPNode(target_call, native_call));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3959 Node* test_native = _gvn.transform(new(C) BoolNode(chk_native, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3960
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 return generate_slow_guard(test_native, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3963
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 //-----------------------generate_method_call----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 // Use generate_method_call to make a slow-call to the real
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 // method if the fast path fails. An alternative would be to
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 // use a stub like OptoRuntime::slow_arraycopy_Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 // This only works for expanding the current library call,
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 // not another intrinsic. (E.g., don't use this for making an
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 // arraycopy call inside of the copyOf intrinsic.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 CallJavaNode*
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 // When compiling the intrinsic method itself, do not use this technique.
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 guarantee(callee() != C->method(), "cannot make slow-call to self");
a61af66fc99e Initial load
duke
parents:
diff changeset
3975
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 ciMethod* method = callee();
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 // ensure the JVMS we have will be correct for this call
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 guarantee(method_id == method->intrinsic_id(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
3979
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 const TypeFunc* tf = TypeFunc::make(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 CallJavaNode* slow_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 if (is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 assert(!is_virtual, "");
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10120
diff changeset
3984 slow_call = new(C) CallStaticJavaNode(C, tf,
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3985 SharedRuntime::get_resolve_static_call_stub(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3986 method, bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 } else if (is_virtual) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3988 null_check_receiver();
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3989 int vtable_index = Method::invalid_vtable_index;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 if (UseInlineCaches) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3991 // Suppress the vtable call
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3993 // hashCode and clone are not a miranda methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 // so the vtable index is fixed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 // No need to use the linkResolver to get it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 vtable_index = method->vtable_index();
12264
b2e698d2276c 8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents: 12190
diff changeset
3997 assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
b2e698d2276c 8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents: 12190
diff changeset
3998 err_msg_res("bad index %d", vtable_index));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4000 slow_call = new(C) CallDynamicJavaNode(tf,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4001 SharedRuntime::get_resolve_virtual_call_stub(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4002 method, vtable_index, bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 } else { // neither virtual nor static: opt_virtual
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4004 null_check_receiver();
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10120
diff changeset
4005 slow_call = new(C) CallStaticJavaNode(C, tf,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 SharedRuntime::get_resolve_opt_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 method, bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 slow_call->set_optimized_virtual(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 set_arguments_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 set_edges_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 return slow_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4014
a61af66fc99e Initial load
duke
parents:
diff changeset
4015
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 //------------------------------inline_native_hashcode--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 // Build special case code for calls to hashCode on an object.
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 assert(is_static == callee()->is_static(), "correct intrinsic selection");
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 assert(!(is_virtual && is_static), "either virtual, special, or static");
a61af66fc99e Initial load
duke
parents:
diff changeset
4021
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT };
a61af66fc99e Initial load
duke
parents:
diff changeset
4023
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4024 RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4025 PhiNode* result_val = new(C) PhiNode(result_reg,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4026 TypeInt::INT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4027 PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4028 PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4029 TypePtr::BOTTOM);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 Node* obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 if (!is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 // Check for hashing null object
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4033 obj = null_check_receiver();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 if (stopped()) return true; // unconditionally null
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 result_reg->init_req(_null_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 result_val->init_req(_null_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 // Do a null check, and return zero if null.
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 // System.identityHashCode(null) == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 obj = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 obj = null_check_oop(obj, &null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 result_reg->init_req(_null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 result_val->init_req(_null_path, _gvn.intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4046
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 // Unconditionally null? Then return right away.
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 if (stopped()) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4049 set_control( result_reg->in(_null_path));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 if (!stopped())
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4051 set_result(result_val->in(_null_path));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4054
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 // After null check, get the object's klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 Node* obj_klass = load_object_klass(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
4057
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 // This call may be virtual (invokevirtual) or bound (invokespecial).
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 // For each case we generate slightly different code.
a61af66fc99e Initial load
duke
parents:
diff changeset
4060
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 // We only go to the fast case code if we pass a number of guards. The
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 // paths which do not pass are accumulated in the slow_region.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4063 RegionNode* slow_region = new (C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4065
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 // If this is a virtual call, we generate a funny guard. We pull out
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 // the vtable entry corresponding to hashCode() from the target object.
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 // If the target method which we are calling happens to be the native
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 // Object hashCode() method, we pass the guard. We do not need this
a61af66fc99e Initial load
duke
parents:
diff changeset
4070 // guard for non-virtual calls -- the caller is known to be the native
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 // Object hashCode().
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 if (is_virtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 generate_virtual_guard(obj_klass, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4075
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 // Get the header out of the object, use LoadMarkNode when available
a61af66fc99e Initial load
duke
parents:
diff changeset
4077 Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
4078 Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4079
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 // Test the header to see if it is unlocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4082 Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4084 Node *chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4085 Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4086
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 generate_slow_guard(test_unlocked, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4088
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 // Get the hash value and check to see that it has been properly assigned.
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 // We depend on hash_mask being at most 32 bits and avoid the use of
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 // vm: see markOop.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4095 Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 // This hack lets the hash bits live anywhere in the mark object now, as long
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
4097 // as the shift drops the relevant bits into the low 32 bits. Note that
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 // Java spec says that HashCode is an int so there's no point in capturing
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 hshifted_header = ConvX2I(hshifted_header);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4101 Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4102
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4104 Node *chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4105 Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4106
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 generate_slow_guard(test_assigned, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4108
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 Node* init_mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 // fill in the rest of the null path:
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 result_io ->init_req(_null_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 result_mem->init_req(_null_path, init_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4113
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 result_val->init_req(_fast_path, hash_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 result_reg->init_req(_fast_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 result_io ->init_req(_fast_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 result_mem->init_req(_fast_path, init_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4118
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 // Generate code for the slow case. We make a call to hashCode().
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 set_control(_gvn.transform(slow_region));
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 // No need for PreserveJVMState, because we're using up the present state.
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 set_all_memory(init_mem);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4124 vmIntrinsics::ID hashCode_id = is_static ? vmIntrinsics::_identityHashCode : vmIntrinsics::_hashCode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4125 CallJavaNode* slow_call = generate_method_call(hashCode_id, is_virtual, is_static);
a61af66fc99e Initial load
duke
parents:
diff changeset
4126 Node* slow_result = set_results_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
4127 // this->control() comes from set_results_for_java_call
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 result_reg->init_req(_slow_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 result_val->init_req(_slow_path, slow_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 result_io ->set_req(_slow_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 result_mem ->set_req(_slow_path, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4133
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 // Return the combined state.
a61af66fc99e Initial load
duke
parents:
diff changeset
4135 set_i_o( _gvn.transform(result_io) );
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4136 set_all_memory( _gvn.transform(result_mem));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4137
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4138 set_result(result_reg, result_val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4139 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4141
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 //---------------------------inline_native_getClass----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4143 // public final native Class<?> java.lang.Object.getClass();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4144 //
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
4145 // Build special case code for calls to getClass on an object.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 bool LibraryCallKit::inline_native_getClass() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4147 Node* obj = null_check_receiver();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4148 if (stopped()) return true;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4149 set_result(load_mirror_from_klass(load_object_klass(obj)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4152
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 //-----------------inline_native_Reflection_getCallerClass---------------------
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4154 // public static native Class<?> sun.reflect.Reflection.getCallerClass();
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4155 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 // In the presence of deep enough inlining, getCallerClass() becomes a no-op.
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 //
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4158 // NOTE: This code must perform the same logic as JVM_GetCallerClass
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4159 // in that it must skip particular security frames and checks for
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4160 // caller sensitive methods.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4161 bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4163 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4167
a61af66fc99e Initial load
duke
parents:
diff changeset
4168 if (!jvms()->has_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4169 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4170 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4171 tty->print_cr(" Bailing out because intrinsic was inlined at top level");
a61af66fc99e Initial load
duke
parents:
diff changeset
4172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4174 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4176
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 // Walk back up the JVM state to find the caller at the required
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4178 // depth.
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4179 JVMState* caller_jvms = jvms();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4180
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4181 // Cf. JVM_GetCallerClass
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4182 // NOTE: Start the loop at depth 1 because the current JVM state does
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4183 // not include the Reflection.getCallerClass() frame.
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4184 for (int n = 1; caller_jvms != NULL; caller_jvms = caller_jvms->caller(), n++) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4185 ciMethod* m = caller_jvms->method();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4186 switch (n) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4187 case 0:
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4188 fatal("current JVM state does not include the Reflection.getCallerClass frame");
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4189 break;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4190 case 1:
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4191 // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass).
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4192 if (!m->caller_sensitive()) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4193 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4194 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4195 tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n);
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4196 }
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4197 #endif
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4198 return false; // bail-out; let JVM_GetCallerClass do the work
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 }
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4200 break;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4201 default:
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4202 if (!m->is_ignored_by_security_stack_walk()) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4203 // We have reached the desired frame; return the holder class.
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4204 // Acquire method holder as java.lang.Class and push as constant.
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4205 ciInstanceKlass* caller_klass = caller_jvms->method()->holder();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4206 ciInstance* caller_mirror = caller_klass->java_mirror();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4207 set_result(makecon(TypeInstPtr::make(caller_mirror)));
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4208
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4210 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4211 tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth());
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4212 tty->print_cr(" JVM state at this point:");
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4213 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4214 ciMethod* m = jvms()->of_depth(i)->method();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4215 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4216 }
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4217 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 #endif
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4219 return true;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4220 }
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4221 break;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4222 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4224
a61af66fc99e Initial load
duke
parents:
diff changeset
4225 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4226 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4227 tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 tty->print_cr(" JVM state at this point:");
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4229 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4230 ciMethod* m = jvms()->of_depth(i)->method();
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4231 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 #endif
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4235
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4236 return false; // bail-out; let JVM_GetCallerClass do the work
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4238
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4240 Node* arg = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4241 Node* result;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4242
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 switch (id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4244 case vmIntrinsics::_floatToRawIntBits: result = new (C) MoveF2INode(arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4245 case vmIntrinsics::_intBitsToFloat: result = new (C) MoveI2FNode(arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4246 case vmIntrinsics::_doubleToRawLongBits: result = new (C) MoveD2LNode(arg); break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4247 case vmIntrinsics::_longBitsToDouble: result = new (C) MoveL2DNode(arg); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4248
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 case vmIntrinsics::_doubleToLongBits: {
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 // two paths (plus control) merge in a wood
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4251 RegionNode *r = new (C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4252 Node *phi = new (C) PhiNode(r, TypeLong::LONG);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4253
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4254 Node *cmpisnan = _gvn.transform(new (C) CmpDNode(arg, arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4255 // Build the boolean node
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4256 Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4257
a61af66fc99e Initial load
duke
parents:
diff changeset
4258 // Branch either way.
a61af66fc99e Initial load
duke
parents:
diff changeset
4259 // NaN case is less traveled, which makes all the difference.
a61af66fc99e Initial load
duke
parents:
diff changeset
4260 IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4261 Node *opt_isnan = _gvn.transform(ifisnan);
a61af66fc99e Initial load
duke
parents:
diff changeset
4262 assert( opt_isnan->is_If(), "Expect an IfNode");
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 IfNode *opt_ifisnan = (IfNode*)opt_isnan;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4264 Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4265
a61af66fc99e Initial load
duke
parents:
diff changeset
4266 set_control(iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4267
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 static const jlong nan_bits = CONST64(0x7ff8000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
4269 Node *slow_result = longcon(nan_bits); // return NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 phi->init_req(1, _gvn.transform( slow_result ));
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 r->init_req(1, iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4272
a61af66fc99e Initial load
duke
parents:
diff changeset
4273 // Else fall through
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4274 Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 set_control(iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4276
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4277 phi->init_req(2, _gvn.transform(new (C) MoveD2LNode(arg)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 r->init_req(2, iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4279
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 // Post merge
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 set_control(_gvn.transform(r));
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 record_for_igvn(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
4283
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4284 C->set_has_split_ifs(true); // Has chance for split-if optimization
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4285 result = phi;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4286 assert(result->bottom_type()->isa_long(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4289
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 case vmIntrinsics::_floatToIntBits: {
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 // two paths (plus control) merge in a wood
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4292 RegionNode *r = new (C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4293 Node *phi = new (C) PhiNode(r, TypeInt::INT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4294
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4295 Node *cmpisnan = _gvn.transform(new (C) CmpFNode(arg, arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4296 // Build the boolean node
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4297 Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4298
a61af66fc99e Initial load
duke
parents:
diff changeset
4299 // Branch either way.
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 // NaN case is less traveled, which makes all the difference.
a61af66fc99e Initial load
duke
parents:
diff changeset
4301 IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 Node *opt_isnan = _gvn.transform(ifisnan);
a61af66fc99e Initial load
duke
parents:
diff changeset
4303 assert( opt_isnan->is_If(), "Expect an IfNode");
a61af66fc99e Initial load
duke
parents:
diff changeset
4304 IfNode *opt_ifisnan = (IfNode*)opt_isnan;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4305 Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4306
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 set_control(iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4308
a61af66fc99e Initial load
duke
parents:
diff changeset
4309 static const jint nan_bits = 0x7fc00000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 Node *slow_result = makecon(TypeInt::make(nan_bits)); // return NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
4311 phi->init_req(1, _gvn.transform( slow_result ));
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 r->init_req(1, iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4313
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 // Else fall through
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4315 Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 set_control(iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4317
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4318 phi->init_req(2, _gvn.transform(new (C) MoveF2INode(arg)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4319 r->init_req(2, iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4320
a61af66fc99e Initial load
duke
parents:
diff changeset
4321 // Post merge
a61af66fc99e Initial load
duke
parents:
diff changeset
4322 set_control(_gvn.transform(r));
a61af66fc99e Initial load
duke
parents:
diff changeset
4323 record_for_igvn(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
4324
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4325 C->set_has_split_ifs(true); // Has chance for split-if optimization
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4326 result = phi;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 assert(result->bottom_type()->isa_int(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
4328 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4330
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4332 fatal_unexpected_iid(id);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4333 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4335 set_result(_gvn.transform(result));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4336 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4338
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 #define XTOP ,top() /*additional argument*/
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 #else //_LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4342 #define XTOP /*no additional argument*/
a61af66fc99e Initial load
duke
parents:
diff changeset
4343 #endif //_LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4344
a61af66fc99e Initial load
duke
parents:
diff changeset
4345 //----------------------inline_unsafe_copyMemory-------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4346 // public native void sun.misc.Unsafe.copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4347 bool LibraryCallKit::inline_unsafe_copyMemory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4348 if (callee()->is_static()) return false; // caller must have the capability!
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4349 null_check_receiver(); // null-check receiver
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4350 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4351
a61af66fc99e Initial load
duke
parents:
diff changeset
4352 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
4353
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4354 Node* src_ptr = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4355 Node* src_off = ConvL2X(argument(2)); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4356 Node* dst_ptr = argument(4); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4357 Node* dst_off = ConvL2X(argument(5)); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4358 Node* size = ConvL2X(argument(7)); // type: long
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4359
a61af66fc99e Initial load
duke
parents:
diff changeset
4360 assert(Unsafe_field_offset_to_byte_offset(11) == 11,
a61af66fc99e Initial load
duke
parents:
diff changeset
4361 "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
4362
a61af66fc99e Initial load
duke
parents:
diff changeset
4363 Node* src = make_unsafe_address(src_ptr, src_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 Node* dst = make_unsafe_address(dst_ptr, dst_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
4365
a61af66fc99e Initial load
duke
parents:
diff changeset
4366 // Conservatively insert a memory barrier on all memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 // Do not let writes of the copy source or destination float below the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4368 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4369
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 // Call it. Note that the length argument is not scaled.
a61af66fc99e Initial load
duke
parents:
diff changeset
4371 make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 OptoRuntime::fast_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 StubRoutines::unsafe_arraycopy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 "unsafe_arraycopy",
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 TypeRawPtr::BOTTOM,
a61af66fc99e Initial load
duke
parents:
diff changeset
4376 src, dst, size XTOP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4377
a61af66fc99e Initial load
duke
parents:
diff changeset
4378 // Do not let reads of the copy destination float above the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4379 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4380
a61af66fc99e Initial load
duke
parents:
diff changeset
4381 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4383
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4384 //------------------------clone_coping-----------------------------------
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4385 // Helper function for inline_native_clone.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4386 void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4387 assert(obj_size != NULL, "");
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4388 Node* raw_obj = alloc_obj->in(1);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4389 assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), "");
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4390
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4391 AllocateNode* alloc = NULL;
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4392 if (ReduceBulkZeroing) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4393 // We will be completely responsible for initializing this object -
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4394 // mark Initialize node as complete.
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4395 alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn);
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4396 // The object was just allocated - there should be no any stores!
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4397 guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), "");
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4398 // Mark as complete_with_arraycopy so that on AllocateNode
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4399 // expansion, we know this AllocateNode is initialized by an array
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4400 // copy and a StoreStore barrier exists after the array copy.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4401 alloc->initialization()->set_complete_with_arraycopy();
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4402 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4403
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4404 // Copy the fastest available way.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4405 // TODO: generate fields copies for small objects instead.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4406 Node* src = obj;
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
4407 Node* dest = alloc_obj;
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4408 Node* size = _gvn.transform(obj_size);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4409
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4410 // Exclude the header but include array length to copy by 8 bytes words.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4411 // Can't use base_offset_in_bytes(bt) since basic type is unknown.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4412 int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() :
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4413 instanceOopDesc::base_offset_in_bytes();
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4414 // base_off:
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4415 // 8 - 32-bit VM
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
4416 // 12 - 64-bit VM, compressed klass
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
4417 // 16 - 64-bit VM, normal klass
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4418 if (base_off % BytesPerLong != 0) {
12226
7944aba7ba41 8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents: 12169
diff changeset
4419 assert(UseCompressedClassPointers, "");
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4420 if (is_array) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4421 // Exclude length to copy by 8 bytes words.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4422 base_off += sizeof(int);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4423 } else {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4424 // Include klass to copy by 8 bytes words.
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4425 base_off = instanceOopDesc::klass_offset_in_bytes();
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4426 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4427 assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment");
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4428 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4429 src = basic_plus_adr(src, base_off);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4430 dest = basic_plus_adr(dest, base_off);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4431
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4432 // Compute the length also, if needed:
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4433 Node* countx = size;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4434 countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(base_off)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4435 countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong) ));
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4436
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4437 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4438 bool disjoint_bases = true;
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4439 generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4440 src, NULL, dest, NULL, countx,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4441 /*dest_uninitialized*/true);
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4442
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4443 // If necessary, emit some card marks afterwards. (Non-arrays only.)
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4444 if (card_mark) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4445 assert(!is_array, "");
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4446 // Put in store barrier for any and all oops we are sticking
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4447 // into this object. (We could avoid this if we could prove
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4448 // that the object type contains no oop fields at all.)
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4449 Node* no_particular_value = NULL;
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4450 Node* no_particular_field = NULL;
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4451 int raw_adr_idx = Compile::AliasIdxRaw;
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4452 post_barrier(control(),
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4453 memory(raw_adr_type),
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
4454 alloc_obj,
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4455 no_particular_field,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4456 raw_adr_idx,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4457 no_particular_value,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4458 T_OBJECT,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4459 false);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4460 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4461
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
4462 // Do not let reads from the cloned object float above the arraycopy.
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4463 if (alloc != NULL) {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4464 // Do not let stores that initialize this object be reordered with
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4465 // a subsequent store that would make this object accessible by
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4466 // other threads.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4467 // Record what AllocateNode this StoreStore protects so that
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4468 // escape analysis can go from the MemBarStoreStoreNode to the
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4469 // AllocateNode and eliminate the MemBarStoreStoreNode if possible
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4470 // based on the escape status of the AllocateNode.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4471 insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4472 } else {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4473 insert_mem_bar(Op_MemBarCPUOrder);
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4474 }
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4475 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4476
a61af66fc99e Initial load
duke
parents:
diff changeset
4477 //------------------------inline_native_clone----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4478 // protected native Object java.lang.Object.clone();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4479 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 // Here are the simple edge cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
4481 // null receiver => normal trap
a61af66fc99e Initial load
duke
parents:
diff changeset
4482 // virtual and clone was overridden => slow path to out-of-line clone
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 // not cloneable or finalizer => slow path to out-of-line Object.clone
a61af66fc99e Initial load
duke
parents:
diff changeset
4484 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 // The general case has two steps, allocation and copying.
a61af66fc99e Initial load
duke
parents:
diff changeset
4486 // Allocation has two cases, and uses GraphKit::new_instance or new_array.
a61af66fc99e Initial load
duke
parents:
diff changeset
4487 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4488 // Copying also has two cases, oop arrays and everything else.
a61af66fc99e Initial load
duke
parents:
diff changeset
4489 // Oop arrays use arrayof_oop_arraycopy (same as System.arraycopy).
a61af66fc99e Initial load
duke
parents:
diff changeset
4490 // Everything else uses the tight inline loop supplied by CopyArrayNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
4491 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4492 // These steps fold up nicely if and when the cloned object's klass
a61af66fc99e Initial load
duke
parents:
diff changeset
4493 // can be sharply typed as an object array, a type array, or an instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
4494 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4495 bool LibraryCallKit::inline_native_clone(bool is_virtual) {
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4496 PhiNode* result_val;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4497
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4498 // Set the reexecute bit for the interpreter to reexecute
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4499 // the bytecode that invokes Object.clone if deoptimization happens.
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4500 { PreserveReexecuteState preexecs(this);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4501 jvms()->set_should_reexecute(true);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4502
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4503 Node* obj = null_check_receiver();
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4504 if (stopped()) return true;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4505
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4506 Node* obj_klass = load_object_klass(obj);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4507 const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr();
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4508 const TypeOopPtr* toop = ((tklass != NULL)
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4509 ? tklass->as_instance_type()
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4510 : TypeInstPtr::NOTNULL);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4511
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4512 // Conservatively insert a memory barrier on all memory slices.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4513 // Do not let writes into the original float below the clone.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4514 insert_mem_bar(Op_MemBarCPUOrder);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4515
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4516 // paths into result_reg:
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4517 enum {
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4518 _slow_path = 1, // out-of-line call to clone method (virtual or not)
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4519 _objArray_path, // plain array allocation, plus arrayof_oop_arraycopy
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4520 _array_path, // plain array allocation, plus arrayof_long_arraycopy
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4521 _instance_path, // plain instance allocation, plus arrayof_long_arraycopy
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4522 PATH_LIMIT
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4523 };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4524 RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4525 result_val = new(C) PhiNode(result_reg,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4526 TypeInstPtr::NOTNULL);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4527 PhiNode* result_i_o = new(C) PhiNode(result_reg, Type::ABIO);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4528 PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4529 TypePtr::BOTTOM);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4530 record_for_igvn(result_reg);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4531
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4532 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4533 int raw_adr_idx = Compile::AliasIdxRaw;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4534
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4535 Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4536 if (array_ctl != NULL) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4537 // It's an array.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4538 PreserveJVMState pjvms(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4539 set_control(array_ctl);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4540 Node* obj_length = load_array_length(obj);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4541 Node* obj_size = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4542 Node* alloc_obj = new_array(obj_klass, obj_length, 0, &obj_size); // no arguments to push
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4543
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4544 if (!use_ReduceInitialCardMarks()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4545 // If it is an oop array, it requires very special treatment,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4546 // because card marking is required on each card of the array.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4547 Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4548 if (is_obja != NULL) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4549 PreserveJVMState pjvms2(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4550 set_control(is_obja);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4551 // Generate a direct call to the right arraycopy function(s).
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4552 bool disjoint_bases = true;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4553 bool length_never_negative = true;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4554 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4555 obj, intcon(0), alloc_obj, intcon(0),
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4556 obj_length,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4557 disjoint_bases, length_never_negative);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4558 result_reg->init_req(_objArray_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4559 result_val->init_req(_objArray_path, alloc_obj);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4560 result_i_o ->set_req(_objArray_path, i_o());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4561 result_mem ->set_req(_objArray_path, reset_memory());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4562 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4563 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4564 // Otherwise, there are no card marks to worry about.
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4565 // (We can dispense with card marks if we know the allocation
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4566 // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4567 // causes the non-eden paths to take compensating steps to
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4568 // simulate a fresh allocation, so that no further
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4569 // card marks are required in compiled code to initialize
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4570 // the object.)
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4571
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4572 if (!stopped()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4573 copy_to_clone(obj, alloc_obj, obj_size, true, false);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4574
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4575 // Present the results of the copy.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4576 result_reg->init_req(_array_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4577 result_val->init_req(_array_path, alloc_obj);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4578 result_i_o ->set_req(_array_path, i_o());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4579 result_mem ->set_req(_array_path, reset_memory());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4581 }
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4582
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4583 // We only go to the instance fast case code if we pass a number of guards.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4584 // The paths which do not pass are accumulated in the slow_region.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4585 RegionNode* slow_region = new (C) RegionNode(1);
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4586 record_for_igvn(slow_region);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4587 if (!stopped()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4588 // It's an instance (we did array above). Make the slow-path tests.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4589 // If this is a virtual call, we generate a funny guard. We grab
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4590 // the vtable entry corresponding to clone() from the target object.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4591 // If the target method which we are calling happens to be the
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4592 // Object clone() method, we pass the guard. We do not need this
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4593 // guard for non-virtual calls; the caller is known to be the native
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4594 // Object clone().
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4595 if (is_virtual) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4596 generate_virtual_guard(obj_klass, slow_region);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4597 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4598
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4599 // The object must be cloneable and must not have a finalizer.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4600 // Both of these conditions may be checked in a single test.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4601 // We could optimize the cloneable test further, but we don't care.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4602 generate_access_flags_guard(obj_klass,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4603 // Test both conditions:
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4604 JVM_ACC_IS_CLONEABLE | JVM_ACC_HAS_FINALIZER,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4605 // Must be cloneable but not finalizer:
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4606 JVM_ACC_IS_CLONEABLE,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4607 slow_region);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4608 }
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4609
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4610 if (!stopped()) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4611 // It's an instance, and it passed the slow-path tests.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4612 PreserveJVMState pjvms(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4613 Node* obj_size = NULL;
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2446
diff changeset
4614 Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size);
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4615
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4616 copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4617
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4618 // Present the results of the slow call.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4619 result_reg->init_req(_instance_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4620 result_val->init_req(_instance_path, alloc_obj);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4621 result_i_o ->set_req(_instance_path, i_o());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4622 result_mem ->set_req(_instance_path, reset_memory());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4624
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4625 // Generate code for the slow case. We make a call to clone().
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4626 set_control(_gvn.transform(slow_region));
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4627 if (!stopped()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4628 PreserveJVMState pjvms(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4629 CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_clone, is_virtual);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4630 Node* slow_result = set_results_for_java_call(slow_call);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4631 // this->control() comes from set_results_for_java_call
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4632 result_reg->init_req(_slow_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4633 result_val->init_req(_slow_path, slow_result);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4634 result_i_o ->set_req(_slow_path, i_o());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4635 result_mem ->set_req(_slow_path, reset_memory());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4636 }
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4637
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4638 // Return the combined state.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4639 set_control( _gvn.transform(result_reg));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4640 set_i_o( _gvn.transform(result_i_o));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4641 set_all_memory( _gvn.transform(result_mem));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4642 } // original reexecute is set back here
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4643
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4644 set_result(_gvn.transform(result_val));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4647
a61af66fc99e Initial load
duke
parents:
diff changeset
4648 //------------------------------basictype2arraycopy----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 address LibraryCallKit::basictype2arraycopy(BasicType t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4650 Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 Node* dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 bool disjoint_bases,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4653 const char* &name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4654 bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4655 const TypeInt* src_offset_inttype = gvn().find_int_type(src_offset);;
a61af66fc99e Initial load
duke
parents:
diff changeset
4656 const TypeInt* dest_offset_inttype = gvn().find_int_type(dest_offset);;
a61af66fc99e Initial load
duke
parents:
diff changeset
4657
a61af66fc99e Initial load
duke
parents:
diff changeset
4658 bool aligned = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 bool disjoint = disjoint_bases;
a61af66fc99e Initial load
duke
parents:
diff changeset
4660
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 // if the offsets are the same, we can treat the memory regions as
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 // disjoint, because either the memory regions are in different arrays,
a61af66fc99e Initial load
duke
parents:
diff changeset
4663 // or they are identical (which we can treat as disjoint.) We can also
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 // treat a copy with a destination index less that the source index
a61af66fc99e Initial load
duke
parents:
diff changeset
4665 // as disjoint since a low->high copy will work correctly in this case.
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 if (src_offset_inttype != NULL && src_offset_inttype->is_con() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4667 dest_offset_inttype != NULL && dest_offset_inttype->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 // both indices are constants
a61af66fc99e Initial load
duke
parents:
diff changeset
4669 int s_offs = src_offset_inttype->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
4670 int d_offs = dest_offset_inttype->get_con();
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
4671 int element_size = type2aelembytes(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4672 aligned = ((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4673 ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4674 if (s_offs >= d_offs) disjoint = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4675 } else if (src_offset == dest_offset && src_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4676 // This can occur if the offsets are identical non-constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
4677 disjoint = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4679
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2444
diff changeset
4680 return StubRoutines::select_arraycopy_function(t, aligned, disjoint, name, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4682
a61af66fc99e Initial load
duke
parents:
diff changeset
4683
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 //------------------------------inline_arraycopy-----------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4685 // public static native void java.lang.System.arraycopy(Object src, int srcPos,
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4686 // Object dest, int destPos,
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4687 // int length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 bool LibraryCallKit::inline_arraycopy() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4689 // Get the arguments.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4690 Node* src = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4691 Node* src_offset = argument(1); // type: int
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4692 Node* dest = argument(2); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4693 Node* dest_offset = argument(3); // type: int
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4694 Node* length = argument(4); // type: int
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4695
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 // Compile time checks. If any of these checks cannot be verified at compile time,
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 // we do not make a fast path for this call. Instead, we let the call remain as it
a61af66fc99e Initial load
duke
parents:
diff changeset
4698 // is. The checks we choose to mandate at compile time are:
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4700 // (1) src and dest are arrays.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4701 const Type* src_type = src->Value(&_gvn);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 const Type* dest_type = dest->Value(&_gvn);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4703 const TypeAryPtr* top_src = src_type->isa_aryptr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4704 const TypeAryPtr* top_dest = dest_type->isa_aryptr();
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4705
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4706 // Do we have the type of src?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4707 bool has_src = (top_src != NULL && top_src->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4708 // Do we have the type of dest?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4709 bool has_dest = (top_dest != NULL && top_dest->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4710 // Is the type for src from speculation?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4711 bool src_spec = false;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4712 // Is the type for dest from speculation?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4713 bool dest_spec = false;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4714
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4715 if (!has_src || !has_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4716 // We don't have sufficient type information, let's see if
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4717 // speculative types can help. We need to have types for both src
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4718 // and dest so that it pays off.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4719
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4720 // Do we already have or could we have type information for src
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4721 bool could_have_src = has_src;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4722 // Do we already have or could we have type information for dest
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4723 bool could_have_dest = has_dest;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4724
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4725 ciKlass* src_k = NULL;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4726 if (!has_src) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4727 src_k = src_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4728 if (src_k != NULL && src_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4729 could_have_src = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4730 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4731 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4732
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4733 ciKlass* dest_k = NULL;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4734 if (!has_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4735 dest_k = dest_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4736 if (dest_k != NULL && dest_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4737 could_have_dest = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4738 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4739 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4740
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4741 if (could_have_src && could_have_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4742 // This is going to pay off so emit the required guards
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4743 if (!has_src) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4744 src = maybe_cast_profiled_obj(src, src_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4745 src_type = _gvn.type(src);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4746 top_src = src_type->isa_aryptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4747 has_src = (top_src != NULL && top_src->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4748 src_spec = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4749 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4750 if (!has_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4751 dest = maybe_cast_profiled_obj(dest, dest_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4752 dest_type = _gvn.type(dest);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4753 top_dest = dest_type->isa_aryptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4754 has_dest = (top_dest != NULL && top_dest->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4755 dest_spec = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4756 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4757 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4758 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4759
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4760 if (!has_src || !has_dest) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4761 // Conservatively insert a memory barrier on all memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 // Do not let writes into the source float below the arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4763 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4764
a61af66fc99e Initial load
duke
parents:
diff changeset
4765 // Call StubRoutines::generic_arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
4766 generate_arraycopy(TypeRawPtr::BOTTOM, T_CONFLICT,
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4767 src, src_offset, dest, dest_offset, length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4768
a61af66fc99e Initial load
duke
parents:
diff changeset
4769 // Do not let reads from the destination float above the arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4770 // Since we cannot type the arrays, we don't know which slices
a61af66fc99e Initial load
duke
parents:
diff changeset
4771 // might be affected. We could restrict this barrier only to those
a61af66fc99e Initial load
duke
parents:
diff changeset
4772 // memory slices which pertain to array elements--but don't bother.
a61af66fc99e Initial load
duke
parents:
diff changeset
4773 if (!InsertMemBarAfterArraycopy)
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 // (If InsertMemBarAfterArraycopy, there is already one in place.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4776 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4778
a61af66fc99e Initial load
duke
parents:
diff changeset
4779 // (2) src and dest arrays must have elements of the same BasicType
a61af66fc99e Initial load
duke
parents:
diff changeset
4780 // Figure out the size and type of the elements we will be copying.
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
4782 BasicType dest_elem = top_dest->klass()->as_array_klass()->element_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 if (src_elem == T_ARRAY) src_elem = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
4784 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
4785
a61af66fc99e Initial load
duke
parents:
diff changeset
4786 if (src_elem != dest_elem || dest_elem == T_VOID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4787 // The component types are not the same or are not recognized. Punt.
a61af66fc99e Initial load
duke
parents:
diff changeset
4788 // (But, avoid the native method wrapper to JVM_ArrayCopy.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4789 generate_slow_arraycopy(TypePtr::BOTTOM,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4790 src, src_offset, dest, dest_offset, length,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4791 /*dest_uninitialized*/false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4792 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4794
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4795 if (src_elem == T_OBJECT) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4796 // If both arrays are object arrays then having the exact types
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4797 // for both will remove the need for a subtype check at runtime
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4798 // before the call and may make it possible to pick a faster copy
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4799 // routine (without a subtype check on every element)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4800 // Do we have the exact type of src?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4801 bool could_have_src = src_spec;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4802 // Do we have the exact type of dest?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4803 bool could_have_dest = dest_spec;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4804 ciKlass* src_k = top_src->klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4805 ciKlass* dest_k = top_dest->klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4806 if (!src_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4807 src_k = src_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4808 if (src_k != NULL && src_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4809 could_have_src = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4810 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4811 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4812 if (!dest_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4813 dest_k = dest_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4814 if (dest_k != NULL && dest_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4815 could_have_dest = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4816 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4817 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4818 if (could_have_src && could_have_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4819 // If we can have both exact types, emit the missing guards
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4820 if (could_have_src && !src_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4821 src = maybe_cast_profiled_obj(src, src_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4822 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4823 if (could_have_dest && !dest_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4824 dest = maybe_cast_profiled_obj(dest, dest_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4825 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4826 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4827 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4828
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4829 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 // We will make a fast path for this call to arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4831
a61af66fc99e Initial load
duke
parents:
diff changeset
4832 // We have the following tests left to perform:
a61af66fc99e Initial load
duke
parents:
diff changeset
4833 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 // (3) src and dest must not be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 // (4) src_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4836 // (5) dest_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4837 // (6) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4838 // (7) src_offset + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 // (8) dest_offset + length must not exceed length of dest.
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 // (9) each element of an oop array must be assignable
a61af66fc99e Initial load
duke
parents:
diff changeset
4841
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4842 RegionNode* slow_region = new (C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4843 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4844
a61af66fc99e Initial load
duke
parents:
diff changeset
4845 // (3) operands must not be null
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4846 // We currently perform our null checks with the null_check routine.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4847 // This means that the null exceptions will be reported in the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
4848 // rather than (correctly) reported inside of the native arraycopy call.
a61af66fc99e Initial load
duke
parents:
diff changeset
4849 // This should be corrected, given time. We do our null check with the
a61af66fc99e Initial load
duke
parents:
diff changeset
4850 // stack pointer restored.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4851 src = null_check(src, T_ARRAY);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4852 dest = null_check(dest, T_ARRAY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4853
a61af66fc99e Initial load
duke
parents:
diff changeset
4854 // (4) src_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4855 generate_negative_guard(src_offset, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4856
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 // (5) dest_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4858 generate_negative_guard(dest_offset, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4859
a61af66fc99e Initial load
duke
parents:
diff changeset
4860 // (6) length must not be negative (moved to generate_arraycopy()).
a61af66fc99e Initial load
duke
parents:
diff changeset
4861 // generate_negative_guard(length, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4862
a61af66fc99e Initial load
duke
parents:
diff changeset
4863 // (7) src_offset + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 generate_limit_guard(src_offset, length,
a61af66fc99e Initial load
duke
parents:
diff changeset
4865 load_array_length(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
4866 slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4867
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 // (8) dest_offset + length must not exceed length of dest.
a61af66fc99e Initial load
duke
parents:
diff changeset
4869 generate_limit_guard(dest_offset, length,
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 load_array_length(dest),
a61af66fc99e Initial load
duke
parents:
diff changeset
4871 slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4872
a61af66fc99e Initial load
duke
parents:
diff changeset
4873 // (9) each element of an oop array must be assignable
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 // The generate_arraycopy subroutine checks this.
a61af66fc99e Initial load
duke
parents:
diff changeset
4875
a61af66fc99e Initial load
duke
parents:
diff changeset
4876 // This is where the memory effects are placed:
a61af66fc99e Initial load
duke
parents:
diff changeset
4877 const TypePtr* adr_type = TypeAryPtr::get_array_body_type(dest_elem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4878 generate_arraycopy(adr_type, dest_elem,
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 src, src_offset, dest, dest_offset, length,
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4880 false, false, slow_region);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4881
a61af66fc99e Initial load
duke
parents:
diff changeset
4882 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4884
a61af66fc99e Initial load
duke
parents:
diff changeset
4885 //-----------------------------generate_arraycopy----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 // Generate an optimized call to arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 // Caller must guard against non-arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
4888 // Caller must determine a common array basic-type for both arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
4889 // Caller must validate offsets against array bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
4890 // The slow_region has already collected guard failure paths
a61af66fc99e Initial load
duke
parents:
diff changeset
4891 // (such as out of bounds length or non-conformable array types).
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 // The generated code has this shape, in general:
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4894 // if (length == 0) return // via zero_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 // slowval = -1
a61af66fc99e Initial load
duke
parents:
diff changeset
4896 // if (types unknown) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4897 // slowval = call generic copy loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4898 // if (slowval == 0) return // via checked_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4899 // } else if (indexes in bounds) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4900 // if ((is object array) && !(array type check)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4901 // slowval = call checked copy loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 // if (slowval == 0) return // via checked_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4903 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4904 // call bulk copy loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 // return // via fast_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4906 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
4907 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
4908 // // adjust params for remaining work:
a61af66fc99e Initial load
duke
parents:
diff changeset
4909 // if (slowval != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4910 // n = -1^slowval; src_offset += n; dest_offset += n; length -= n
a61af66fc99e Initial load
duke
parents:
diff changeset
4911 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
4912 // slow_region:
a61af66fc99e Initial load
duke
parents:
diff changeset
4913 // call slow arraycopy(src, src_offset, dest, dest_offset, length)
a61af66fc99e Initial load
duke
parents:
diff changeset
4914 // return // via slow_call_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4916 // This routine is used from several intrinsics: System.arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 // Object.clone (the array subcase), and Arrays.copyOf[Range].
a61af66fc99e Initial load
duke
parents:
diff changeset
4918 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4919 void
a61af66fc99e Initial load
duke
parents:
diff changeset
4920 LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
4921 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
4922 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 Node* dest, Node* dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4924 Node* copy_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
4925 bool disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 bool length_never_negative,
a61af66fc99e Initial load
duke
parents:
diff changeset
4927 RegionNode* slow_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4928
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 if (slow_region == NULL) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4930 slow_region = new(C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4931 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4933
a61af66fc99e Initial load
duke
parents:
diff changeset
4934 Node* original_dest = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
4935 AllocateArrayNode* alloc = NULL; // used for zeroing, if needed
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4936 bool dest_uninitialized = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4937
a61af66fc99e Initial load
duke
parents:
diff changeset
4938 // See if this is the initialization of a newly-allocated array.
a61af66fc99e Initial load
duke
parents:
diff changeset
4939 // If so, we will take responsibility here for initializing it to zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
4940 // (Note: Because tightly_coupled_allocation performs checks on the
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 // out-edges of the dest, we need to avoid making derived pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 // from it until we have checked its uses.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4943 if (ReduceBulkZeroing
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 && !ZeroTLAB // pointless if already zeroed
a61af66fc99e Initial load
duke
parents:
diff changeset
4945 && basic_elem_type != T_CONFLICT // avoid corner case
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
4946 && !src->eqv_uncast(dest)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 && ((alloc = tightly_coupled_allocation(dest, slow_region))
a61af66fc99e Initial load
duke
parents:
diff changeset
4948 != NULL)
34
545c277a3ecf 6667581: Don't generate initialization (by 0) code for arrays with size 0
kvn
parents: 29
diff changeset
4949 && _gvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4950 && alloc->maybe_set_complete(&_gvn)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4951 // "You break it, you buy it."
a61af66fc99e Initial load
duke
parents:
diff changeset
4952 InitializeNode* init = alloc->initialization();
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 assert(init->is_complete(), "we just did this");
3961
a92cdbac8b9e 7081933: Use zeroing elimination optimization for large array
kvn
parents: 3742
diff changeset
4954 init->set_complete_with_arraycopy();
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4955 assert(dest->is_CheckCastPP(), "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 assert(dest->in(0)->in(0) == init, "dest pinned");
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory
a61af66fc99e Initial load
duke
parents:
diff changeset
4958 // From this point on, every exit path is responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
4959 // initializing any non-copied parts of the object to zero.
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4960 // Also, if this flag is set we make sure that arraycopy interacts properly
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4961 // with G1, eliding pre-barriers. See CR 6627983.
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4962 dest_uninitialized = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4963 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 // No zeroing elimination here.
a61af66fc99e Initial load
duke
parents:
diff changeset
4965 alloc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 //original_dest = dest;
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4967 //dest_uninitialized = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4969
a61af66fc99e Initial load
duke
parents:
diff changeset
4970 // Results are placed here:
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 enum { fast_path = 1, // normal void-returning assembly stub
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 checked_path = 2, // special assembly stub with cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 slow_call_path = 3, // something went wrong; call the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
4974 zero_path = 4, // bypass when length of copy is zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4975 bcopy_path = 5, // copy primitive array by 64-bit blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 PATH_LIMIT = 6
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4978 RegionNode* result_region = new(C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4979 PhiNode* result_i_o = new(C) PhiNode(result_region, Type::ABIO);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4980 PhiNode* result_memory = new(C) PhiNode(result_region, Type::MEMORY, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 record_for_igvn(result_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4982 _gvn.set_type_bottom(result_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
4983 _gvn.set_type_bottom(result_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 assert(adr_type != TypePtr::BOTTOM, "must be RawMem or a T[] slice");
a61af66fc99e Initial load
duke
parents:
diff changeset
4985
a61af66fc99e Initial load
duke
parents:
diff changeset
4986 // The slow_control path:
a61af66fc99e Initial load
duke
parents:
diff changeset
4987 Node* slow_control;
a61af66fc99e Initial load
duke
parents:
diff changeset
4988 Node* slow_i_o = i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 Node* slow_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
4990 debug_only(slow_control = (Node*) badAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
4991
a61af66fc99e Initial load
duke
parents:
diff changeset
4992 // Checked control path:
a61af66fc99e Initial load
duke
parents:
diff changeset
4993 Node* checked_control = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
4994 Node* checked_mem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4995 Node* checked_i_o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 Node* checked_value = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4997
a61af66fc99e Initial load
duke
parents:
diff changeset
4998 if (basic_elem_type == T_CONFLICT) {
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4999 assert(!dest_uninitialized, "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5000 Node* cv = generate_generic_arraycopy(adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5001 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5002 copy_length, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5003 if (cv == NULL) cv = intcon(-1); // failure (no stub available)
a61af66fc99e Initial load
duke
parents:
diff changeset
5004 checked_control = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5005 checked_i_o = i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
5006 checked_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 checked_value = cv;
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 set_control(top()); // no fast path
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5010
a61af66fc99e Initial load
duke
parents:
diff changeset
5011 Node* not_pos = generate_nonpositive_guard(copy_length, length_never_negative);
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 if (not_pos != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5013 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 set_control(not_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
5015
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 // (6) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
5017 if (!length_never_negative) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5018 generate_negative_guard(copy_length, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5020
836
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5021 // copy_length is 0.
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5022 if (!stopped() && dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5023 Node* dest_length = alloc->in(AllocateNode::ALength);
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
5024 if (copy_length->eqv_uncast(dest_length)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5025 || _gvn.find_int_con(dest_length, 1) <= 0) {
836
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5026 // There is no zeroing to do. No need for a secondary raw memory barrier.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5027 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5028 // Clear the whole thing since there are no source elements to copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
5029 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 intcon(0), NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5031 alloc->in(AllocateNode::AllocSize));
836
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5032 // Use a secondary InitializeNode as raw memory barrier.
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5033 // Currently it is needed only on this path since other
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5034 // paths have stub or runtime calls as raw memory barriers.
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5035 InitializeNode* init = insert_mem_bar_volatile(Op_Initialize,
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5036 Compile::AliasIdxRaw,
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5037 top())->as_Initialize();
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5038 init->set_complete(&_gvn); // (there is no corresponding AllocateNode)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5041
a61af66fc99e Initial load
duke
parents:
diff changeset
5042 // Present the results of the fast call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5043 result_region->init_req(zero_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 result_i_o ->init_req(zero_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5045 result_memory->init_req(zero_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5047
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5048 if (!stopped() && dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 // We have to initialize the *uncopied* part of the array to zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
5050 // The copy destination is the slice dest[off..off+len]. The other slices
a61af66fc99e Initial load
duke
parents:
diff changeset
5051 // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length].
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 Node* dest_size = alloc->in(AllocateNode::AllocSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
5053 Node* dest_length = alloc->in(AllocateNode::ALength);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5054 Node* dest_tail = _gvn.transform(new(C) AddINode(dest_offset,
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5055 copy_length));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5056
a61af66fc99e Initial load
duke
parents:
diff changeset
5057 // If there is a head section that needs zeroing, do it now.
a61af66fc99e Initial load
duke
parents:
diff changeset
5058 if (find_int_con(dest_offset, -1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 intcon(0), dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5061 NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5063
a61af66fc99e Initial load
duke
parents:
diff changeset
5064 // Next, perform a dynamic check on the tail length.
a61af66fc99e Initial load
duke
parents:
diff changeset
5065 // It is often zero, and we can win big if we prove this.
a61af66fc99e Initial load
duke
parents:
diff changeset
5066 // There are two wins: Avoid generating the ClearArray
a61af66fc99e Initial load
duke
parents:
diff changeset
5067 // with its attendant messy index arithmetic, and upgrade
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 // the copy to a more hardware-friendly word size of 64 bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 Node* tail_ctl = NULL;
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
5070 if (!stopped() && !dest_tail->eqv_uncast(dest_length)) {
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5071 Node* cmp_lt = _gvn.transform(new(C) CmpINode(dest_tail, dest_length));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5072 Node* bol_lt = _gvn.transform(new(C) BoolNode(cmp_lt, BoolTest::lt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5073 tail_ctl = generate_slow_guard(bol_lt, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5074 assert(tail_ctl != NULL || !stopped(), "must be an outcome");
a61af66fc99e Initial load
duke
parents:
diff changeset
5075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5076
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 // At this point, let's assume there is no tail.
a61af66fc99e Initial load
duke
parents:
diff changeset
5078 if (!stopped() && alloc != NULL && basic_elem_type != T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5079 // There is no tail. Try an upgrade to a 64-bit copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
5080 bool didit = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5081 { PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 didit = generate_block_arraycopy(adr_type, basic_elem_type, alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
5083 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5084 dest_size, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5085 if (didit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5086 // Present the results of the block-copying fast call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5087 result_region->init_req(bcopy_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 result_i_o ->init_req(bcopy_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5089 result_memory->init_req(bcopy_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5092 if (didit)
a61af66fc99e Initial load
duke
parents:
diff changeset
5093 set_control(top()); // no regular fast path
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5095
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 // Clear the tail, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
5097 if (tail_ctl != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5098 Node* notail_ctl = stopped() ? NULL : control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5099 set_control(tail_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5100 if (notail_ctl == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5101 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5102 dest_tail, NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 dest_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
5104 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 // Make a local merge.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5106 Node* done_ctl = new(C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5107 Node* done_mem = new(C) PhiNode(done_ctl, Type::MEMORY, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 done_ctl->init_req(1, notail_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 done_mem->init_req(1, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5111 dest_tail, NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 dest_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 done_ctl->init_req(2, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 done_mem->init_req(2, memory(adr_type));
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5115 set_control( _gvn.transform(done_ctl));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 set_memory( _gvn.transform(done_mem), adr_type );
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5120
a61af66fc99e Initial load
duke
parents:
diff changeset
5121 BasicType copy_type = basic_elem_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 assert(basic_elem_type != T_ARRAY, "caller must fix this");
a61af66fc99e Initial load
duke
parents:
diff changeset
5123 if (!stopped() && copy_type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5124 // If src and dest have compatible element types, we can copy bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 // Types S[] and D[] are compatible if D is a supertype of S.
a61af66fc99e Initial load
duke
parents:
diff changeset
5126 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 // If they are not, we will use checked_oop_disjoint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 // which performs a fast optimistic per-oop check, and backs off
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 // further to JVM_ArrayCopy on the first per-oop check that fails.
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 // (Actually, we don't move raw bits only; the GC requires card marks.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5131
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
5132 // Get the Klass* for both src and dest
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 Node* src_klass = load_object_klass(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 Node* dest_klass = load_object_klass(dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
5135
a61af66fc99e Initial load
duke
parents:
diff changeset
5136 // Generate the subtype check.
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 // This might fold up statically, or then again it might not.
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 // Non-static example: Copying List<String>.elements to a new String[].
a61af66fc99e Initial load
duke
parents:
diff changeset
5140 // The backing store for a List<String> is always an Object[],
a61af66fc99e Initial load
duke
parents:
diff changeset
5141 // but its elements are always type String, if the generic types
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 // are correct at the source level.
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5144 // Test S[] against D[], not S against D, because (probably)
a61af66fc99e Initial load
duke
parents:
diff changeset
5145 // the secondary supertype cache is less busy for S[] than S.
a61af66fc99e Initial load
duke
parents:
diff changeset
5146 // This usually only matters when D is an interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 Node* not_subtype_ctrl = gen_subtype_check(src_klass, dest_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 // Plug failing path into checked_oop_disjoint_arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 if (not_subtype_ctrl != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5151 set_control(not_subtype_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5152 // (At this point we can assume disjoint_bases, since types differ.)
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6804
diff changeset
5153 int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5154 Node* p1 = basic_plus_adr(dest_klass, ek_offset);
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 163
diff changeset
5155 Node* n1 = LoadKlassNode::make(_gvn, immutable_memory(), p1, TypeRawPtr::BOTTOM);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5156 Node* dest_elem_klass = _gvn.transform(n1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5157 Node* cv = generate_checkcast_arraycopy(adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5158 dest_elem_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
5159 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5160 ConvI2X(copy_length), dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5161 if (cv == NULL) cv = intcon(-1); // failure (no stub available)
a61af66fc99e Initial load
duke
parents:
diff changeset
5162 checked_control = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5163 checked_i_o = i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
5164 checked_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5165 checked_value = cv;
a61af66fc99e Initial load
duke
parents:
diff changeset
5166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5167 // At this point we know we do not need type checks on oop stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
5168
a61af66fc99e Initial load
duke
parents:
diff changeset
5169 // Let's see if we need card marks:
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 if (alloc != NULL && use_ReduceInitialCardMarks()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5171 // If we do not need card marks, copy using the jint or jlong stub.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5172 copy_type = LP64_ONLY(UseCompressedOops ? T_INT : T_LONG) NOT_LP64(T_INT);
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
5173 assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5174 "sizes agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
5175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5177
a61af66fc99e Initial load
duke
parents:
diff changeset
5178 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 // Generate the fast path, if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5181 generate_unchecked_arraycopy(adr_type, copy_type, disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
5182 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5183 ConvI2X(copy_length), dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5184
a61af66fc99e Initial load
duke
parents:
diff changeset
5185 // Present the results of the fast call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5186 result_region->init_req(fast_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5187 result_i_o ->init_req(fast_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5188 result_memory->init_req(fast_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5190
a61af66fc99e Initial load
duke
parents:
diff changeset
5191 // Here are all the slow paths up to this point, in one bundle:
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 slow_control = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5193 if (slow_region != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5194 slow_control = _gvn.transform(slow_region);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5195 DEBUG_ONLY(slow_region = (RegionNode*)badAddress);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5196
a61af66fc99e Initial load
duke
parents:
diff changeset
5197 set_control(checked_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
5198 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5199 // Clean up after the checked call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 // The returned value is either 0 or -1^K,
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 // where K = number of partially transferred array elements.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5202 Node* cmp = _gvn.transform(new(C) CmpINode(checked_value, intcon(0)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5203 Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5204 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
5205
a61af66fc99e Initial load
duke
parents:
diff changeset
5206 // If it is 0, we are done, so transfer to the end.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5207 Node* checks_done = _gvn.transform(new(C) IfTrueNode(iff));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 result_region->init_req(checked_path, checks_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 result_i_o ->init_req(checked_path, checked_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
5210 result_memory->init_req(checked_path, checked_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5211
a61af66fc99e Initial load
duke
parents:
diff changeset
5212 // If it is not zero, merge into the slow call.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5213 set_control( _gvn.transform(new(C) IfFalseNode(iff) ));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5214 RegionNode* slow_reg2 = new(C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5215 PhiNode* slow_i_o2 = new(C) PhiNode(slow_reg2, Type::ABIO);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5216 PhiNode* slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 record_for_igvn(slow_reg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5218 slow_reg2 ->init_req(1, slow_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
5219 slow_i_o2 ->init_req(1, slow_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 slow_mem2 ->init_req(1, slow_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5221 slow_reg2 ->init_req(2, control());
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
5222 slow_i_o2 ->init_req(2, checked_i_o);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
5223 slow_mem2 ->init_req(2, checked_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5224
a61af66fc99e Initial load
duke
parents:
diff changeset
5225 slow_control = _gvn.transform(slow_reg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5226 slow_i_o = _gvn.transform(slow_i_o2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5227 slow_mem = _gvn.transform(slow_mem2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5228
a61af66fc99e Initial load
duke
parents:
diff changeset
5229 if (alloc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5230 // We'll restart from the very beginning, after zeroing the whole thing.
a61af66fc99e Initial load
duke
parents:
diff changeset
5231 // This can cause double writes, but that's OK since dest is brand new.
a61af66fc99e Initial load
duke
parents:
diff changeset
5232 // So we ignore the low 31 bits of the value returned from the stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
5233 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5234 // We must continue the copy exactly where it failed, or else
a61af66fc99e Initial load
duke
parents:
diff changeset
5235 // another thread might see the wrong number of writes to dest.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5236 Node* checked_offset = _gvn.transform(new(C) XorINode(checked_value, intcon(-1)));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5237 Node* slow_offset = new(C) PhiNode(slow_reg2, TypeInt::INT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5238 slow_offset->init_req(1, intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
5239 slow_offset->init_req(2, checked_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5240 slow_offset = _gvn.transform(slow_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5241
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 // Adjust the arguments by the conditionally incoming offset.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5243 Node* src_off_plus = _gvn.transform(new(C) AddINode(src_offset, slow_offset));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5244 Node* dest_off_plus = _gvn.transform(new(C) AddINode(dest_offset, slow_offset));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5245 Node* length_minus = _gvn.transform(new(C) SubINode(copy_length, slow_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5246
a61af66fc99e Initial load
duke
parents:
diff changeset
5247 // Tweak the node variables to adjust the code produced below:
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 src_offset = src_off_plus;
a61af66fc99e Initial load
duke
parents:
diff changeset
5249 dest_offset = dest_off_plus;
a61af66fc99e Initial load
duke
parents:
diff changeset
5250 copy_length = length_minus;
a61af66fc99e Initial load
duke
parents:
diff changeset
5251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5253
a61af66fc99e Initial load
duke
parents:
diff changeset
5254 set_control(slow_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
5255 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5256 // Generate the slow path, if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
5257 PreserveJVMState pjvms(this); // replace_in_map may trash the map
a61af66fc99e Initial load
duke
parents:
diff changeset
5258
a61af66fc99e Initial load
duke
parents:
diff changeset
5259 set_memory(slow_mem, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5260 set_i_o(slow_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
5261
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5262 if (dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5263 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5264 intcon(0), NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5265 alloc->in(AllocateNode::AllocSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
5266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5267
a61af66fc99e Initial load
duke
parents:
diff changeset
5268 generate_slow_arraycopy(adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5269 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5270 copy_length, /*dest_uninitialized*/false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5271
a61af66fc99e Initial load
duke
parents:
diff changeset
5272 result_region->init_req(slow_call_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5273 result_i_o ->init_req(slow_call_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5274 result_memory->init_req(slow_call_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5276
a61af66fc99e Initial load
duke
parents:
diff changeset
5277 // Remove unused edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
5278 for (uint i = 1; i < result_region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5279 if (result_region->in(i) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5280 result_region->init_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
5281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5282
a61af66fc99e Initial load
duke
parents:
diff changeset
5283 // Finished; return the combined state.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5284 set_control( _gvn.transform(result_region));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5285 set_i_o( _gvn.transform(result_i_o) );
a61af66fc99e Initial load
duke
parents:
diff changeset
5286 set_memory( _gvn.transform(result_memory), adr_type );
a61af66fc99e Initial load
duke
parents:
diff changeset
5287
a61af66fc99e Initial load
duke
parents:
diff changeset
5288 // The memory edges above are precise in order to model effects around
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
5289 // array copies accurately to allow value numbering of field loads around
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5290 // arraycopy. Such field loads, both before and after, are common in Java
a61af66fc99e Initial load
duke
parents:
diff changeset
5291 // collections and similar classes involving header/array data structures.
a61af66fc99e Initial load
duke
parents:
diff changeset
5292 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5293 // But with low number of register or when some registers are used or killed
a61af66fc99e Initial load
duke
parents:
diff changeset
5294 // by arraycopy calls it causes registers spilling on stack. See 6544710.
a61af66fc99e Initial load
duke
parents:
diff changeset
5295 // The next memory barrier is added to avoid it. If the arraycopy can be
a61af66fc99e Initial load
duke
parents:
diff changeset
5296 // optimized away (which it can, sometimes) then we can manually remove
a61af66fc99e Initial load
duke
parents:
diff changeset
5297 // the membar also.
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
5298 //
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
5299 // Do not let reads from the cloned object float above the arraycopy.
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5300 if (alloc != NULL) {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5301 // Do not let stores that initialize this object be reordered with
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5302 // a subsequent store that would make this object accessible by
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5303 // other threads.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5304 // Record what AllocateNode this StoreStore protects so that
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5305 // escape analysis can go from the MemBarStoreStoreNode to the
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5306 // AllocateNode and eliminate the MemBarStoreStoreNode if possible
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5307 // based on the escape status of the AllocateNode.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5308 insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5309 } else if (InsertMemBarAfterArraycopy)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5310 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
5311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5312
a61af66fc99e Initial load
duke
parents:
diff changeset
5313
a61af66fc99e Initial load
duke
parents:
diff changeset
5314 // Helper function which determines if an arraycopy immediately follows
a61af66fc99e Initial load
duke
parents:
diff changeset
5315 // an allocation, with no intervening tests or other escapes for the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 AllocateArrayNode*
a61af66fc99e Initial load
duke
parents:
diff changeset
5317 LibraryCallKit::tightly_coupled_allocation(Node* ptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 RegionNode* slow_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 if (stopped()) return NULL; // no fast path
a61af66fc99e Initial load
duke
parents:
diff changeset
5320 if (C->AliasLevel() == 0) return NULL; // no MergeMems around
a61af66fc99e Initial load
duke
parents:
diff changeset
5321
a61af66fc99e Initial load
duke
parents:
diff changeset
5322 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(ptr, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5323 if (alloc == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5324
a61af66fc99e Initial load
duke
parents:
diff changeset
5325 Node* rawmem = memory(Compile::AliasIdxRaw);
a61af66fc99e Initial load
duke
parents:
diff changeset
5326 // Is the allocation's memory state untouched?
a61af66fc99e Initial load
duke
parents:
diff changeset
5327 if (!(rawmem->is_Proj() && rawmem->in(0)->is_Initialize())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5328 // Bail out if there have been raw-memory effects since the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 // (Example: There might have been a call or safepoint.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5330 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5332 rawmem = rawmem->in(0)->as_Initialize()->memory(Compile::AliasIdxRaw);
a61af66fc99e Initial load
duke
parents:
diff changeset
5333 if (!(rawmem->is_Proj() && rawmem->in(0) == alloc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5334 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5336
a61af66fc99e Initial load
duke
parents:
diff changeset
5337 // There must be no unexpected observers of this allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5338 for (DUIterator_Fast imax, i = ptr->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5339 Node* obs = ptr->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5340 if (obs != this->map()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5341 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5344
a61af66fc99e Initial load
duke
parents:
diff changeset
5345 // This arraycopy must unconditionally follow the allocation of the ptr.
a61af66fc99e Initial load
duke
parents:
diff changeset
5346 Node* alloc_ctl = ptr->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5347 assert(just_allocated_object(alloc_ctl) == ptr, "most recent allo");
a61af66fc99e Initial load
duke
parents:
diff changeset
5348
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 Node* ctl = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5350 while (ctl != alloc_ctl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5351 // There may be guards which feed into the slow_region.
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 // Any other control flow means that we might not get a chance
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 // to finish initializing the allocated object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5354 if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5355 IfNode* iff = ctl->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
5356 Node* not_ctl = iff->proj_out(1 - ctl->as_Proj()->_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
5357 assert(not_ctl != NULL && not_ctl != ctl, "found alternate");
a61af66fc99e Initial load
duke
parents:
diff changeset
5358 if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5359 ctl = iff->in(0); // This test feeds the known slow_region.
a61af66fc99e Initial load
duke
parents:
diff changeset
5360 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5362 // One more try: Various low-level checks bottom out in
a61af66fc99e Initial load
duke
parents:
diff changeset
5363 // uncommon traps. If the debug-info of the trap omits
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 // any reference to the allocation, as we've already
a61af66fc99e Initial load
duke
parents:
diff changeset
5365 // observed, then there can be no objection to the trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5366 bool found_trap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5367 for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5368 Node* obs = not_ctl->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
5369 if (obs->in(0) == not_ctl && obs->is_Call() &&
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1746
diff changeset
5370 (obs->as_Call()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5371 found_trap = true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
5372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5374 if (found_trap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5375 ctl = iff->in(0); // This test feeds a harmless uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5376 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5379 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5381
a61af66fc99e Initial load
duke
parents:
diff changeset
5382 // If we get this far, we have an allocation which immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
5383 // precedes the arraycopy, and we can take over zeroing the new object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5384 // The arraycopy will finish the initialization, and provide
a61af66fc99e Initial load
duke
parents:
diff changeset
5385 // a new control state to which we will anchor the destination pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
5386
a61af66fc99e Initial load
duke
parents:
diff changeset
5387 return alloc;
a61af66fc99e Initial load
duke
parents:
diff changeset
5388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5389
a61af66fc99e Initial load
duke
parents:
diff changeset
5390 // Helper for initialization of arrays, creating a ClearArray.
a61af66fc99e Initial load
duke
parents:
diff changeset
5391 // It writes zero bits in [start..end), within the body of an array object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5392 // The memory effects are all chained onto the 'adr_type' alias category.
a61af66fc99e Initial load
duke
parents:
diff changeset
5393 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5394 // Since the object is otherwise uninitialized, we are free
a61af66fc99e Initial load
duke
parents:
diff changeset
5395 // to put a little "slop" around the edges of the cleared area,
a61af66fc99e Initial load
duke
parents:
diff changeset
5396 // as long as it does not go back into the array's header,
a61af66fc99e Initial load
duke
parents:
diff changeset
5397 // or beyond the array end within the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5398 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5399 // The lower edge can be rounded down to the nearest jint and the
a61af66fc99e Initial load
duke
parents:
diff changeset
5400 // upper edge can be rounded up to the nearest MinObjAlignmentInBytes.
a61af66fc99e Initial load
duke
parents:
diff changeset
5401 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5402 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
5403 // adr_type memory slice where writes are generated
a61af66fc99e Initial load
duke
parents:
diff changeset
5404 // dest oop of the destination array
a61af66fc99e Initial load
duke
parents:
diff changeset
5405 // basic_elem_type element type of the destination
a61af66fc99e Initial load
duke
parents:
diff changeset
5406 // slice_idx array index of first element to store
a61af66fc99e Initial load
duke
parents:
diff changeset
5407 // slice_len number of elements to store (or NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5408 // dest_size total size in bytes of the array object
a61af66fc99e Initial load
duke
parents:
diff changeset
5409 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5410 // Exactly one of slice_len or dest_size must be non-NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
5411 // If dest_size is non-NULL, zeroing extends to the end of the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5412 // If slice_len is non-NULL, the slice_idx value must be a constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
5413 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5414 LibraryCallKit::generate_clear_array(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5415 Node* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5416 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5417 Node* slice_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
5418 Node* slice_len,
a61af66fc99e Initial load
duke
parents:
diff changeset
5419 Node* dest_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5420 // one or the other but not both of slice_len and dest_size:
a61af66fc99e Initial load
duke
parents:
diff changeset
5421 assert((slice_len != NULL? 1: 0) + (dest_size != NULL? 1: 0) == 1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5422 if (slice_len == NULL) slice_len = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5423 if (dest_size == NULL) dest_size = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5424
a61af66fc99e Initial load
duke
parents:
diff changeset
5425 // operate on this memory slice:
a61af66fc99e Initial load
duke
parents:
diff changeset
5426 Node* mem = memory(adr_type); // memory slice to operate on
a61af66fc99e Initial load
duke
parents:
diff changeset
5427
a61af66fc99e Initial load
duke
parents:
diff changeset
5428 // scaling and rounding of indexes:
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
5429 int scale = exact_log2(type2aelembytes(basic_elem_type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5430 int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5431 int clear_low = (-1 << scale) & (BytesPerInt - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5432 int bump_bit = (-1 << scale) & BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
5433
a61af66fc99e Initial load
duke
parents:
diff changeset
5434 // determine constant starts and ends
a61af66fc99e Initial load
duke
parents:
diff changeset
5435 const intptr_t BIG_NEG = -128;
a61af66fc99e Initial load
duke
parents:
diff changeset
5436 assert(BIG_NEG + 2*abase < 0, "neg enough");
a61af66fc99e Initial load
duke
parents:
diff changeset
5437 intptr_t slice_idx_con = (intptr_t) find_int_con(slice_idx, BIG_NEG);
a61af66fc99e Initial load
duke
parents:
diff changeset
5438 intptr_t slice_len_con = (intptr_t) find_int_con(slice_len, BIG_NEG);
a61af66fc99e Initial load
duke
parents:
diff changeset
5439 if (slice_len_con == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5440 return; // nothing to do here
a61af66fc99e Initial load
duke
parents:
diff changeset
5441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5442 intptr_t start_con = (abase + (slice_idx_con << scale)) & ~clear_low;
a61af66fc99e Initial load
duke
parents:
diff changeset
5443 intptr_t end_con = find_intptr_t_con(dest_size, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5444 if (slice_idx_con >= 0 && slice_len_con >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5445 assert(end_con < 0, "not two cons");
a61af66fc99e Initial load
duke
parents:
diff changeset
5446 end_con = round_to(abase + ((slice_idx_con + slice_len_con) << scale),
a61af66fc99e Initial load
duke
parents:
diff changeset
5447 BytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
5448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5449
a61af66fc99e Initial load
duke
parents:
diff changeset
5450 if (start_con >= 0 && end_con >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5451 // Constant start and end. Simple.
a61af66fc99e Initial load
duke
parents:
diff changeset
5452 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5453 start_con, end_con, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5454 } else if (start_con >= 0 && dest_size != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5455 // Constant start, pre-rounded end after the tail of the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
5456 Node* end = dest_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
5457 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5458 start_con, end, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5459 } else if (start_con >= 0 && slice_len != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5460 // Constant start, non-constant end. End needs rounding up.
a61af66fc99e Initial load
duke
parents:
diff changeset
5461 // End offset = round_up(abase + ((slice_idx_con + slice_len) << scale), 8)
a61af66fc99e Initial load
duke
parents:
diff changeset
5462 intptr_t end_base = abase + (slice_idx_con << scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5463 int end_round = (-1 << scale) & (BytesPerLong - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5464 Node* end = ConvI2X(slice_len);
a61af66fc99e Initial load
duke
parents:
diff changeset
5465 if (scale != 0)
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5466 end = _gvn.transform(new(C) LShiftXNode(end, intcon(scale) ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5467 end_base += end_round;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5468 end = _gvn.transform(new(C) AddXNode(end, MakeConX(end_base)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5469 end = _gvn.transform(new(C) AndXNode(end, MakeConX(~end_round)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5470 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5471 start_con, end, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5472 } else if (start_con < 0 && dest_size != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5473 // Non-constant start, pre-rounded end after the tail of the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
5474 // This is almost certainly a "round-to-end" operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5475 Node* start = slice_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
5476 start = ConvI2X(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
5477 if (scale != 0)
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5478 start = _gvn.transform(new(C) LShiftXNode( start, intcon(scale) ));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5479 start = _gvn.transform(new(C) AddXNode(start, MakeConX(abase)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5480 if ((bump_bit | clear_low) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5481 int to_clear = (bump_bit | clear_low);
a61af66fc99e Initial load
duke
parents:
diff changeset
5482 // Align up mod 8, then store a jint zero unconditionally
a61af66fc99e Initial load
duke
parents:
diff changeset
5483 // just before the mod-8 boundary.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5484 if (((abase + bump_bit) & ~to_clear) - bump_bit
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5485 < arrayOopDesc::length_offset_in_bytes() + BytesPerInt) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5486 bump_bit = 0;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5487 assert((abase & to_clear) == 0, "array base must be long-aligned");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5488 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5489 // Bump 'start' up to (or past) the next jint boundary:
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5490 start = _gvn.transform(new(C) AddXNode(start, MakeConX(bump_bit)));
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5491 assert((abase & clear_low) == 0, "array base must be int-aligned");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5492 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5493 // Round bumped 'start' down to jlong boundary in body of array.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5494 start = _gvn.transform(new(C) AndXNode(start, MakeConX(~to_clear)));
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5495 if (bump_bit != 0) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5496 // Store a zero to the immediately preceding jint:
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5497 Node* x1 = _gvn.transform(new(C) AddXNode(start, MakeConX(-bump_bit)));
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5498 Node* p1 = basic_plus_adr(dest, x1);
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5499 mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT, MemNode::unordered);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5500 mem = _gvn.transform(mem);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5501 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5503 Node* end = dest_size; // pre-rounded
a61af66fc99e Initial load
duke
parents:
diff changeset
5504 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5505 start, end, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5506 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5507 // Non-constant start, unrounded non-constant end.
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 // (Nobody zeroes a random midsection of an array using this routine.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 ShouldNotReachHere(); // fix caller
a61af66fc99e Initial load
duke
parents:
diff changeset
5510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5511
a61af66fc99e Initial load
duke
parents:
diff changeset
5512 // Done.
a61af66fc99e Initial load
duke
parents:
diff changeset
5513 set_memory(mem, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5515
a61af66fc99e Initial load
duke
parents:
diff changeset
5516
a61af66fc99e Initial load
duke
parents:
diff changeset
5517 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
5518 LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5519 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5520 AllocateNode* alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
5521 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5522 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5523 Node* dest_size, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5524 // See if there is an advantage from block transfer.
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
5525 int scale = exact_log2(type2aelembytes(basic_elem_type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5526 if (scale >= LogBytesPerLong)
a61af66fc99e Initial load
duke
parents:
diff changeset
5527 return false; // it is already a block transfer
a61af66fc99e Initial load
duke
parents:
diff changeset
5528
a61af66fc99e Initial load
duke
parents:
diff changeset
5529 // Look at the alignment of the starting offsets.
a61af66fc99e Initial load
duke
parents:
diff changeset
5530 int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
3742
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5531
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5532 intptr_t src_off_con = (intptr_t) find_int_con(src_offset, -1);
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5533 intptr_t dest_off_con = (intptr_t) find_int_con(dest_offset, -1);
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5534 if (src_off_con < 0 || dest_off_con < 0)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5535 // At present, we can only understand constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
5536 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5537
3742
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5538 intptr_t src_off = abase + (src_off_con << scale);
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5539 intptr_t dest_off = abase + (dest_off_con << scale);
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5540
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5541 if (((src_off | dest_off) & (BytesPerLong-1)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5542 // Non-aligned; too bad.
a61af66fc99e Initial load
duke
parents:
diff changeset
5543 // One more chance: Pick off an initial 32-bit word.
a61af66fc99e Initial load
duke
parents:
diff changeset
5544 // This is a common case, since abase can be odd mod 8.
a61af66fc99e Initial load
duke
parents:
diff changeset
5545 if (((src_off | dest_off) & (BytesPerLong-1)) == BytesPerInt &&
a61af66fc99e Initial load
duke
parents:
diff changeset
5546 ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5547 Node* sptr = basic_plus_adr(src, src_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5548 Node* dptr = basic_plus_adr(dest, dest_off);
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5549 Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5550 store_to_memory(control(), dptr, sval, T_INT, adr_type, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5551 src_off += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
5552 dest_off += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
5553 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5554 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5557 assert(src_off % BytesPerLong == 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5558 assert(dest_off % BytesPerLong == 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5559
a61af66fc99e Initial load
duke
parents:
diff changeset
5560 // Do this copy by giant steps.
a61af66fc99e Initial load
duke
parents:
diff changeset
5561 Node* sptr = basic_plus_adr(src, src_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 Node* dptr = basic_plus_adr(dest, dest_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 Node* countx = dest_size;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5564 countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(dest_off)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5565 countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5566
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 bool disjoint_bases = true; // since alloc != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5569 sptr, NULL, dptr, NULL, countx, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5570
a61af66fc99e Initial load
duke
parents:
diff changeset
5571 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5573
a61af66fc99e Initial load
duke
parents:
diff changeset
5574
a61af66fc99e Initial load
duke
parents:
diff changeset
5575 // Helper function; generates code for the slow case.
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 // We make a call to a runtime method which emulates the native method,
a61af66fc99e Initial load
duke
parents:
diff changeset
5577 // but without the native wrapper overhead.
a61af66fc99e Initial load
duke
parents:
diff changeset
5578 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5579 LibraryCallKit::generate_slow_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5580 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5581 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5582 Node* copy_length, bool dest_uninitialized) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5583 assert(!dest_uninitialized, "Invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5584 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON,
a61af66fc99e Initial load
duke
parents:
diff changeset
5585 OptoRuntime::slow_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5586 OptoRuntime::slow_arraycopy_Java(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5587 "slow_arraycopy", adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5588 src, src_offset, dest, dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5589 copy_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
5590
a61af66fc99e Initial load
duke
parents:
diff changeset
5591 // Handle exceptions thrown by this fellow:
a61af66fc99e Initial load
duke
parents:
diff changeset
5592 make_slow_call_ex(call, env()->Throwable_klass(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
5593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5594
a61af66fc99e Initial load
duke
parents:
diff changeset
5595 // Helper function; generates code for cases requiring runtime checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
5596 Node*
a61af66fc99e Initial load
duke
parents:
diff changeset
5597 LibraryCallKit::generate_checkcast_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5598 Node* dest_elem_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
5599 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5600 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5601 Node* copy_length, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5602 if (stopped()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5603
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5604 address copyfunc_addr = StubRoutines::checkcast_arraycopy(dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5605 if (copyfunc_addr == NULL) { // Stub was not generated, go slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
5606 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5608
a61af66fc99e Initial load
duke
parents:
diff changeset
5609 // Pick out the parameters required to perform a store-check
a61af66fc99e Initial load
duke
parents:
diff changeset
5610 // for the target array. This is an optimistic check. It will
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 // look in each non-null element's class, at the desired klass's
a61af66fc99e Initial load
duke
parents:
diff changeset
5612 // super_check_offset, for the desired klass.
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
5613 int sco_offset = in_bytes(Klass::super_check_offset_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5614 Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5615 Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr(), TypeInt::INT, MemNode::unordered);
1844
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1748
diff changeset
5616 Node* check_offset = ConvI2X(_gvn.transform(n3));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5617 Node* check_value = dest_elem_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
5618
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 Node* src_start = array_element_address(src, src_offset, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
5620 Node* dest_start = array_element_address(dest, dest_offset, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
5621
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 // (We know the arrays are never conjoint, because their types differ.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5623 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5624 OptoRuntime::checkcast_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5625 copyfunc_addr, "checkcast_arraycopy", adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5626 // five arguments, of which two are
a61af66fc99e Initial load
duke
parents:
diff changeset
5627 // intptr_t (jlong in LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 src_start, dest_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 copy_length XTOP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 check_offset XTOP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5631 check_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
5632
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5633 return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5635
a61af66fc99e Initial load
duke
parents:
diff changeset
5636
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 // Helper function; generates code for cases requiring runtime checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
5638 Node*
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 LibraryCallKit::generate_generic_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5640 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5641 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5642 Node* copy_length, bool dest_uninitialized) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5643 assert(!dest_uninitialized, "Invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5644 if (stopped()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5645 address copyfunc_addr = StubRoutines::generic_arraycopy();
a61af66fc99e Initial load
duke
parents:
diff changeset
5646 if (copyfunc_addr == NULL) { // Stub was not generated, go slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
5647 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5649
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5651 OptoRuntime::generic_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5652 copyfunc_addr, "generic_arraycopy", adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 src, src_offset, dest, dest_offset, copy_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
5654
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5655 return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5657
a61af66fc99e Initial load
duke
parents:
diff changeset
5658 // Helper function; generates the fast out-of-line call to an arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
5659 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5660 LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5661 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5662 bool disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
5663 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5664 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5665 Node* copy_length, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5666 if (stopped()) return; // nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
5667
a61af66fc99e Initial load
duke
parents:
diff changeset
5668 Node* src_start = src;
a61af66fc99e Initial load
duke
parents:
diff changeset
5669 Node* dest_start = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
5670 if (src_offset != NULL || dest_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5671 assert(src_offset != NULL && dest_offset != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5672 src_start = array_element_address(src, src_offset, basic_elem_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5673 dest_start = array_element_address(dest, dest_offset, basic_elem_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5675
a61af66fc99e Initial load
duke
parents:
diff changeset
5676 // Figure out which arraycopy runtime method to call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5677 const char* copyfunc_name = "arraycopy";
a61af66fc99e Initial load
duke
parents:
diff changeset
5678 address copyfunc_addr =
a61af66fc99e Initial load
duke
parents:
diff changeset
5679 basictype2arraycopy(basic_elem_type, src_offset, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5680 disjoint_bases, copyfunc_name, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5681
a61af66fc99e Initial load
duke
parents:
diff changeset
5682 // Call it. Note that the count_ix value is not scaled to a byte-size.
a61af66fc99e Initial load
duke
parents:
diff changeset
5683 make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5684 OptoRuntime::fast_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5685 copyfunc_addr, copyfunc_name, adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5686 src_start, dest_start, copy_length XTOP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5687 }
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5688
7637
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5689 //-------------inline_encodeISOArray-----------------------------------
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5690 // encode char[] to byte[] in ISO_8859_1
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5691 bool LibraryCallKit::inline_encodeISOArray() {
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5692 assert(callee()->signature()->size() == 5, "encodeISOArray has 5 parameters");
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5693 // no receiver since it is static method
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5694 Node *src = argument(0);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5695 Node *src_offset = argument(1);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5696 Node *dst = argument(2);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5697 Node *dst_offset = argument(3);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5698 Node *length = argument(4);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5699
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5700 const Type* src_type = src->Value(&_gvn);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5701 const Type* dst_type = dst->Value(&_gvn);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5702 const TypeAryPtr* top_src = src_type->isa_aryptr();
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5703 const TypeAryPtr* top_dest = dst_type->isa_aryptr();
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5704 if (top_src == NULL || top_src->klass() == NULL ||
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5705 top_dest == NULL || top_dest->klass() == NULL) {
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5706 // failed array check
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5707 return false;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5708 }
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5709
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5710 // Figure out the size and type of the elements we will be copying.
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5711 BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5712 BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5713 if (src_elem != T_CHAR || dst_elem != T_BYTE) {
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5714 return false;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5715 }
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5716 Node* src_start = array_element_address(src, src_offset, src_elem);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5717 Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5718 // 'src_start' points to src array + scaled offset
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5719 // 'dst_start' points to dst array + scaled offset
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5720
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5721 const TypeAryPtr* mtype = TypeAryPtr::BYTES;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5722 Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5723 enc = _gvn.transform(enc);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5724 Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc));
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5725 set_memory(res_mem, mtype);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5726 set_result(enc);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5727 return true;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5728 }
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5729
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5730 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5731 * Calculate CRC32 for byte.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5732 * int java.util.zip.CRC32.update(int crc, int b)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5733 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5734 bool LibraryCallKit::inline_updateCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5735 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5736 assert(callee()->signature()->size() == 2, "update has 2 parameters");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5737 // no receiver since it is static method
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5738 Node* crc = argument(0); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5739 Node* b = argument(1); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5740
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5741 /*
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5742 * int c = ~ crc;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5743 * b = timesXtoThe32[(b ^ c) & 0xFF];
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5744 * b = b ^ (c >>> 8);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5745 * crc = ~b;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5746 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5747
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5748 Node* M1 = intcon(-1);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5749 crc = _gvn.transform(new (C) XorINode(crc, M1));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5750 Node* result = _gvn.transform(new (C) XorINode(crc, b));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5751 result = _gvn.transform(new (C) AndINode(result, intcon(0xFF)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5752
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5753 Node* base = makecon(TypeRawPtr::make(StubRoutines::crc_table_addr()));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5754 Node* offset = _gvn.transform(new (C) LShiftINode(result, intcon(0x2)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5755 Node* adr = basic_plus_adr(top(), base, ConvI2X(offset));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5756 result = make_load(control(), adr, TypeInt::INT, T_INT, MemNode::unordered);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5757
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5758 crc = _gvn.transform(new (C) URShiftINode(crc, intcon(8)));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5759 result = _gvn.transform(new (C) XorINode(crc, result));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5760 result = _gvn.transform(new (C) XorINode(result, M1));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5761 set_result(result);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5762 return true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5763 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5764
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5765 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5766 * Calculate CRC32 for byte[] array.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5767 * int java.util.zip.CRC32.updateBytes(int crc, byte[] buf, int off, int len)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5768 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5769 bool LibraryCallKit::inline_updateBytesCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5770 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5771 assert(callee()->signature()->size() == 4, "updateBytes has 4 parameters");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5772 // no receiver since it is static method
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5773 Node* crc = argument(0); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5774 Node* src = argument(1); // type: oop
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5775 Node* offset = argument(2); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5776 Node* length = argument(3); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5777
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5778 const Type* src_type = src->Value(&_gvn);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5779 const TypeAryPtr* top_src = src_type->isa_aryptr();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5780 if (top_src == NULL || top_src->klass() == NULL) {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5781 // failed array check
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5782 return false;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5783 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5784
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5785 // Figure out the size and type of the elements we will be copying.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5786 BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5787 if (src_elem != T_BYTE) {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5788 return false;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5789 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5790
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5791 // 'src_start' points to src array + scaled offset
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5792 Node* src_start = array_element_address(src, offset, src_elem);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5793
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5794 // We assume that range check is done by caller.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5795 // TODO: generate range check (offset+length < src.length) in debug VM.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5796
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5797 // Call the stub.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5798 address stubAddr = StubRoutines::updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5799 const char *stubName = "updateBytesCRC32";
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5800
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5801 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5802 stubAddr, stubName, TypePtr::BOTTOM,
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5803 crc, src_start, length);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5804 Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5805 set_result(result);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5806 return true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5807 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5808
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5809 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5810 * Calculate CRC32 for ByteBuffer.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5811 * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5812 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5813 bool LibraryCallKit::inline_updateByteBufferCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5814 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5815 assert(callee()->signature()->size() == 5, "updateByteBuffer has 4 parameters and one is long");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5816 // no receiver since it is static method
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5817 Node* crc = argument(0); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5818 Node* src = argument(1); // type: long
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5819 Node* offset = argument(3); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5820 Node* length = argument(4); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5821
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5822 src = ConvL2X(src); // adjust Java long to machine word
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5823 Node* base = _gvn.transform(new (C) CastX2PNode(src));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5824 offset = ConvI2X(offset);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5825
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5826 // 'src_start' points to src array + scaled offset
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5827 Node* src_start = basic_plus_adr(top(), base, offset);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5828
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5829 // Call the stub.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5830 address stubAddr = StubRoutines::updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5831 const char *stubName = "updateBytesCRC32";
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5832
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5833 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5834 stubAddr, stubName, TypePtr::BOTTOM,
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5835 crc, src_start, length);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5836 Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5837 set_result(result);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5838 return true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5839 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5840
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5841 //----------------------------inline_reference_get----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5842 // public T java.lang.ref.Reference.get();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5843 bool LibraryCallKit::inline_reference_get() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5844 const int referent_offset = java_lang_ref_Reference::referent_offset;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5845 guarantee(referent_offset > 0, "should have already been set");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5846
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5847 // Get the argument:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5848 Node* reference_obj = null_check_receiver();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5849 if (stopped()) return true;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5850
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5851 Node* adr = basic_plus_adr(reference_obj, reference_obj, referent_offset);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5852
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5853 ciInstanceKlass* klass = env()->Object_klass();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5854 const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5855
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5856 Node* no_ctrl = NULL;
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5857 Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT, MemNode::unordered);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5858
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5859 // Use the pre-barrier to record the value in the referent field
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5860 pre_barrier(false /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5861 control(),
3258
edd9b016deb6 7036021: G1: build failure on win64 and linux with hs21 in jdk6 build environment
johnc
parents: 3255
diff changeset
5862 NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */,
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5863 result /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5864 T_OBJECT);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5865
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
5866 // Add memory barrier to prevent commoning reads from this field
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
5867 // across safepoint since GC can change its value.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
5868 insert_mem_bar(Op_MemBarCPUOrder);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
5869
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5870 set_result(result);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5871 return true;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5872 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5873
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5874
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5875 Node * LibraryCallKit::load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString,
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5876 bool is_exact=true, bool is_static=false) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5877
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5878 const TypeInstPtr* tinst = _gvn.type(fromObj)->isa_instptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5879 assert(tinst != NULL, "obj is null");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5880 assert(tinst->klass()->is_loaded(), "obj is not loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5881 assert(!is_exact || tinst->klass_is_exact(), "klass not exact");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5882
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5883 ciField* field = tinst->klass()->as_instance_klass()->get_field_by_name(ciSymbol::make(fieldName),
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5884 ciSymbol::make(fieldTypeString),
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5885 is_static);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5886 if (field == NULL) return (Node *) NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5887 assert (field != NULL, "undefined field");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5888
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5889 // Next code copied from Parse::do_get_xxx():
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5890
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5891 // Compute address and memory type.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5892 int offset = field->offset_in_bytes();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5893 bool is_vol = field->is_volatile();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5894 ciType* field_klass = field->type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5895 assert(field_klass->is_loaded(), "should be loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5896 const TypePtr* adr_type = C->alias_type(field)->adr_type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5897 Node *adr = basic_plus_adr(fromObj, fromObj, offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5898 BasicType bt = field->layout_type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5899
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5900 // Build the resultant type of the load
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5901 const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5902
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5903 // Build the load.
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 13019
diff changeset
5904 Node* loadedField = make_load(NULL, adr, type, bt, adr_type, MemNode::unordered, is_vol);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5905 return loadedField;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5906 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5907
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5908
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5909 //------------------------------inline_aescrypt_Block-----------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5910 bool LibraryCallKit::inline_aescrypt_Block(vmIntrinsics::ID id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5911 address stubAddr;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5912 const char *stubName;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5913 assert(UseAES, "need AES instruction support");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5914
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5915 switch(id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5916 case vmIntrinsics::_aescrypt_encryptBlock:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5917 stubAddr = StubRoutines::aescrypt_encryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5918 stubName = "aescrypt_encryptBlock";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5919 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5920 case vmIntrinsics::_aescrypt_decryptBlock:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5921 stubAddr = StubRoutines::aescrypt_decryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5922 stubName = "aescrypt_decryptBlock";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5923 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5924 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5925 if (stubAddr == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5926
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5927 Node* aescrypt_object = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5928 Node* src = argument(1);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5929 Node* src_offset = argument(2);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5930 Node* dest = argument(3);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5931 Node* dest_offset = argument(4);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5932
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5933 // (1) src and dest are arrays.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5934 const Type* src_type = src->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5935 const Type* dest_type = dest->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5936 const TypeAryPtr* top_src = src_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5937 const TypeAryPtr* top_dest = dest_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5938 assert (top_src != NULL && top_src->klass() != NULL && top_dest != NULL && top_dest->klass() != NULL, "args are strange");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5939
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5940 // for the quick and dirty code we will skip all the checks.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5941 // we are just trying to get the call to be generated.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5942 Node* src_start = src;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5943 Node* dest_start = dest;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5944 if (src_offset != NULL || dest_offset != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5945 assert(src_offset != NULL && dest_offset != NULL, "");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5946 src_start = array_element_address(src, src_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5947 dest_start = array_element_address(dest, dest_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5948 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5949
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5950 // now need to get the start of its expanded key array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5951 // this requires a newer class file that has this array as littleEndian ints, otherwise we revert to java
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5952 Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5953 if (k_start == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5954
14261
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5955 if (Matcher::pass_original_key_for_aes()) {
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5956 // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5957 // compatibility issues between Java key expansion and SPARC crypto instructions
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5958 Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5959 if (original_k_start == NULL) return false;
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5960
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5961 // Call the stub.
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5962 make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5963 stubAddr, stubName, TypePtr::BOTTOM,
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5964 src_start, dest_start, k_start, original_k_start);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5965 } else {
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5966 // Call the stub.
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5967 make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5968 stubAddr, stubName, TypePtr::BOTTOM,
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5969 src_start, dest_start, k_start);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5970 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5971
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5972 return true;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5973 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5974
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5975 //------------------------------inline_cipherBlockChaining_AESCrypt-----------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5976 bool LibraryCallKit::inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5977 address stubAddr;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5978 const char *stubName;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5979
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5980 assert(UseAES, "need AES instruction support");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5981
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5982 switch(id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5983 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5984 stubAddr = StubRoutines::cipherBlockChaining_encryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5985 stubName = "cipherBlockChaining_encryptAESCrypt";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5986 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5987 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5988 stubAddr = StubRoutines::cipherBlockChaining_decryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5989 stubName = "cipherBlockChaining_decryptAESCrypt";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5990 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5991 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5992 if (stubAddr == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5993
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5994 Node* cipherBlockChaining_object = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5995 Node* src = argument(1);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5996 Node* src_offset = argument(2);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5997 Node* len = argument(3);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5998 Node* dest = argument(4);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5999 Node* dest_offset = argument(5);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6000
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6001 // (1) src and dest are arrays.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6002 const Type* src_type = src->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6003 const Type* dest_type = dest->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6004 const TypeAryPtr* top_src = src_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6005 const TypeAryPtr* top_dest = dest_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6006 assert (top_src != NULL && top_src->klass() != NULL
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6007 && top_dest != NULL && top_dest->klass() != NULL, "args are strange");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6008
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6009 // checks are the responsibility of the caller
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6010 Node* src_start = src;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6011 Node* dest_start = dest;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6012 if (src_offset != NULL || dest_offset != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6013 assert(src_offset != NULL && dest_offset != NULL, "");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6014 src_start = array_element_address(src, src_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6015 dest_start = array_element_address(dest, dest_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6016 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6017
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6018 // if we are in this set of code, we "know" the embeddedCipher is an AESCrypt object
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6019 // (because of the predicated logic executed earlier).
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6020 // so we cast it here safely.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6021 // this requires a newer class file that has this array as littleEndian ints, otherwise we revert to java
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6022
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6023 Node* embeddedCipherObj = load_field_from_object(cipherBlockChaining_object, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6024 if (embeddedCipherObj == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6025
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6026 // cast it to what we know it will be at runtime
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6027 const TypeInstPtr* tinst = _gvn.type(cipherBlockChaining_object)->isa_instptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6028 assert(tinst != NULL, "CBC obj is null");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6029 assert(tinst->klass()->is_loaded(), "CBC obj is not loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6030 ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6031 if (!klass_AESCrypt->is_loaded()) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6032
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6033 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6034 const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6035 const TypeOopPtr* xtype = aklass->as_instance_type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6036 Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6037 aescrypt_object = _gvn.transform(aescrypt_object);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6038
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6039 // we need to get the start of the aescrypt_object's expanded key array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6040 Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6041 if (k_start == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6042
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6043 // similarly, get the start address of the r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6044 Node* objRvec = load_field_from_object(cipherBlockChaining_object, "r", "[B", /*is_exact*/ false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6045 if (objRvec == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6046 Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6047
14261
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6048 Node* cbcCrypt;
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6049 if (Matcher::pass_original_key_for_aes()) {
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6050 // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6051 // compatibility issues between Java key expansion and SPARC crypto instructions
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6052 Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6053 if (original_k_start == NULL) return false;
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6054
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6055 // Call the stub, passing src_start, dest_start, k_start, r_start, src_len and original_k_start
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6056 cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6057 OptoRuntime::cipherBlockChaining_aescrypt_Type(),
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6058 stubAddr, stubName, TypePtr::BOTTOM,
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6059 src_start, dest_start, k_start, r_start, len, original_k_start);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6060 } else {
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6061 // Call the stub, passing src_start, dest_start, k_start, r_start and src_len
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6062 cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6063 OptoRuntime::cipherBlockChaining_aescrypt_Type(),
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6064 stubAddr, stubName, TypePtr::BOTTOM,
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6065 src_start, dest_start, k_start, r_start, len);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6066 }
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6067
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6068 // return cipher length (int)
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6069 Node* retvalue = _gvn.transform(new (C) ProjNode(cbcCrypt, TypeFunc::Parms));
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6070 set_result(retvalue);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6071 return true;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6072 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6073
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6074 //------------------------------get_key_start_from_aescrypt_object-----------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6075 Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6076 Node* objAESCryptKey = load_field_from_object(aescrypt_object, "K", "[I", /*is_exact*/ false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6077 assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6078 if (objAESCryptKey == NULL) return (Node *) NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6079
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6080 // now have the array, need to get the start address of the K array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6081 Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6082 return k_start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6083 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6084
14261
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6085 //------------------------------get_original_key_start_from_aescrypt_object-----------------------
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6086 Node * LibraryCallKit::get_original_key_start_from_aescrypt_object(Node *aescrypt_object) {
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6087 Node* objAESCryptKey = load_field_from_object(aescrypt_object, "lastKey", "[B", /*is_exact*/ false);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6088 assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6089 if (objAESCryptKey == NULL) return (Node *) NULL;
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6090
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6091 // now have the array, need to get the start address of the lastKey array
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6092 Node* original_k_start = array_element_address(objAESCryptKey, intcon(0), T_BYTE);
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6093 return original_k_start;
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6094 }
00f5eff62d18 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6095
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6096 //----------------------------inline_cipherBlockChaining_AESCrypt_predicate----------------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6097 // Return node representing slow path of predicate check.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6098 // the pseudo code we want to emulate with this predicate is:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6099 // for encryption:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6100 // if (embeddedCipherObj instanceof AESCrypt) do_intrinsic, else do_javapath
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6101 // for decryption:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6102 // if ((embeddedCipherObj instanceof AESCrypt) && (cipher!=plain)) do_intrinsic, else do_javapath
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6103 // note cipher==plain is more conservative than the original java code but that's OK
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6104 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6105 Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6106 // First, check receiver for NULL since it is virtual method.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6107 Node* objCBC = argument(0);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
6108 objCBC = null_check(objCBC);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6109
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6110 if (stopped()) return NULL; // Always NULL
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6111
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6112 // Load embeddedCipher field of CipherBlockChaining object.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6113 Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6114
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6115 // get AESCrypt klass for instanceOf check
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6116 // AESCrypt might not be loaded yet if some other SymmetricCipher got us to this compile point
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6117 // will have same classloader as CipherBlockChaining object
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6118 const TypeInstPtr* tinst = _gvn.type(objCBC)->isa_instptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6119 assert(tinst != NULL, "CBCobj is null");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6120 assert(tinst->klass()->is_loaded(), "CBCobj is not loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6121
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6122 // we want to do an instanceof comparison against the AESCrypt class
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6123 ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6124 if (!klass_AESCrypt->is_loaded()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6125 // if AESCrypt is not even loaded, we never take the intrinsic fast path
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6126 Node* ctrl = control();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6127 set_control(top()); // no regular fast path
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6128 return ctrl;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6129 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6130 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6131
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6132 Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6133 Node* cmp_instof = _gvn.transform(new (C) CmpINode(instof, intcon(1)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6134 Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6135
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6136 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6137
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6138 // for encryption, we are done
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6139 if (!decrypting)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6140 return instof_false; // even if it is NULL
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6141
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6142 // for decryption, we need to add a further check to avoid
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6143 // taking the intrinsic path when cipher and plain are the same
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6144 // see the original java code for why.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6145 RegionNode* region = new(C) RegionNode(3);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6146 region->init_req(1, instof_false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6147 Node* src = argument(1);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
6148 Node* dest = argument(4);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6149 Node* cmp_src_dest = _gvn.transform(new (C) CmpPNode(src, dest));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6150 Node* bool_src_dest = _gvn.transform(new (C) BoolNode(cmp_src_dest, BoolTest::eq));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6151 Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6152 region->init_req(2, src_dest_conjoint);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6153
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6154 record_for_igvn(region);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6155 return _gvn.transform(region);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6156 }