annotate src/share/vm/opto/library_call.cpp @ 17716:cdb71841f4bc

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 04d32e7fad07
children 085b304a1cc5
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);
17670
04d32e7fad07 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()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
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
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
1940 case vmIntrinsics::_dsqrt: return Matcher::has_match_rule(Op_SqrtD) ? inline_math(id) : false;
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.
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 if (is_store)
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2634
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 // Memory barrier to prevent normal and 'unsafe' accesses from
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 // bypassing each other. Happens after null checks, so the
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 // exception paths do not take memory state from the memory barrier,
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 // so there's no problems making a strong assert about mixing users
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 // of safe & unsafe memory. Otherwise fails in a CTW of rt.jar
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 // around 5701, class sun/reflect/UnsafeBooleanFieldAccessorImpl.
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
2642
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 if (!is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 Node* p = make_load(control(), adr, value_type, type, adr_type, is_volatile);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2645 // load value
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 case T_INT:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2652 case T_LONG:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 case T_FLOAT:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2654 case T_DOUBLE:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2655 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 case T_OBJECT:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
2657 if (need_read_barrier) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2658 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
2659 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 case T_ADDRESS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 // Cast to an int type.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2663 p = _gvn.transform(new (C) CastP2XNode(NULL, p));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 p = ConvX2L(p);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2665 break;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2666 default:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2667 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2670 // 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
2671 // 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
2672 // 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
2673 // point is fine.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2674 set_result(p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 // place effect of store into memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 val = dstore_rounding(val);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 case T_ADDRESS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 // Repackage the long as a pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 val = ConvL2X(val);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
2684 val = _gvn.transform(new (C) CastX2PNode(val));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2687
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 if (type != T_OBJECT ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile);
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 // Possibly an oop being stored to Java heap or native memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 // oop to Java heap.
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 787
diff changeset
2694 (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // We can't tell at compile time if we are storing in the Java heap or outside
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 // of it. So we need to emit code to conditionally do the proper type of
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 // store.
a61af66fc99e Initial load
duke
parents:
diff changeset
2699
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2700 IdealKit ideal(this);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2701 #define __ ideal.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // QQQ who knows what probability is here??
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2703 __ 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
2704 // Sync IdealKit and graphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2705 sync_kit(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2706 Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2707 // Update IdealKit memory.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2708 __ sync_kit(this);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2709 } __ else_(); {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2710 __ store(__ ctrl(), adr, val, type, alias_type->index(), is_volatile);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2711 } __ end_if();
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2712 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2405
diff changeset
2713 final_sync(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 836
diff changeset
2714 #undef __
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2718
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 if (is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 if (!is_store)
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 insert_mem_bar(Op_MemBarAcquire);
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 else
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 insert_mem_bar(Op_MemBarVolatile);
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2725
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
2727
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 //----------------------------inline_unsafe_prefetch----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2732
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 bool LibraryCallKit::inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 // Check the signatures.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2738 ciSignature* sig = callee()->signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 // Object getObject(Object base, int/long offset), etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 BasicType rtype = sig->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 if (!is_native_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 assert(sig->count() == 2, "oop prefetch has 2 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 assert(sig->type_at(0)->basic_type() == T_OBJECT, "prefetch base is object");
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 assert(sig->type_at(1)->basic_type() == T_LONG, "prefetcha offset is correct");
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 assert(sig->count() == 1, "native prefetch has 1 argument");
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 assert(sig->type_at(0)->basic_type() == T_LONG, "prefetch base is long");
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2753
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
2755
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2756 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
2757 if (!is_static) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2758 null_check_receiver();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2759 if (stopped()) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2760 return true;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2761 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2762 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2763
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 // Build address expression. See the code in inline_unsafe_access.
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 Node *adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 if (!is_native_ptr) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2767 // 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
2768 Node* base = argument(idx + 0); // type: oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 // 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
2770 Node* offset = argument(idx + 1); // type: long
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 // to be plain byte offsets, which are also the same as those accepted
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // by oopDesc::field_base.
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 assert(Unsafe_field_offset_to_byte_offset(11) == 11,
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // 32-bit machines ignore the high half!
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 } else {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2780 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
2781 ptr = ConvL2X(ptr); // adjust Java long to machine word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 adr = make_unsafe_address(NULL, ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2784
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 // Generate the read or write prefetch
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 Node *prefetch;
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 if (is_store) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2788 prefetch = new (C) PrefetchWriteNode(i_o(), adr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2790 prefetch = new (C) PrefetchReadNode(i_o(), adr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 prefetch->init_req(0, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 set_i_o(_gvn.transform(prefetch));
a61af66fc99e Initial load
duke
parents:
diff changeset
2794
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2797
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2798 //----------------------------inline_unsafe_load_store----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2799 // 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
2800 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2801 // LS_cmpxchg:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2802 // 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
2803 // 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
2804 // 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
2805 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2806 // LS_xadd:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2807 // 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
2808 // 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
2809 //
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2810 // LS_xchg:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2811 // 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
2812 // 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
2813 // 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
2814 //
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2815 bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 // This basic scheme here is the same as inline_unsafe_access, but
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 // differs in enough details that combining them would make the code
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 // overly confusing. (This is a true fact! I originally combined
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 // them, but even I was confused by it!) As much code/comments as
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 // possible are retained from inline_unsafe_access though to make
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
2821 // the correspondences clearer. - dl
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2822
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 if (callee()->is_static()) return false; // caller must have the capability!
a61af66fc99e Initial load
duke
parents:
diff changeset
2824
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 #ifndef PRODUCT
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2826 BasicType rtype;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 ResourceMark rm;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2829 // Check the signatures.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2830 ciSignature* sig = callee()->signature();
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2831 rtype = sig->return_type()->basic_type();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2832 if (kind == LS_xadd || kind == LS_xchg) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2833 // Check the signatures.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 #ifdef ASSERT
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2835 assert(rtype == type, "get and set must return the expected type");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2836 assert(sig->count() == 3, "get and set has 3 arguments");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2837 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
2838 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
2839 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
2840 #endif // ASSERT
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2841 } else if (kind == LS_cmpxchg) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2842 // Check the signatures.
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2843 #ifdef ASSERT
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2844 assert(rtype == T_BOOLEAN, "CAS must return boolean");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2845 assert(sig->count() == 4, "CAS has 4 arguments");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2846 assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2847 assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long");
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2848 #endif // ASSERT
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2849 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2850 ShouldNotReachHere();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2851 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2854
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
2856
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2857 // Get arguments:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2858 Node* receiver = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2859 Node* base = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2860 Node* offset = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2861 Node* oldval = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2862 Node* newval = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2863 if (kind == LS_cmpxchg) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2864 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
2865 receiver = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2866 base = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2867 offset = argument(2); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2868 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
2869 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
2870 } 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
2871 receiver = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2872 base = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2873 offset = argument(2); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2874 oldval = NULL;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2875 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
2876 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2877
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2878 // Null check receiver.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
2879 receiver = null_check(receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2883
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 // Build field offset expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 // to be plain byte offsets, which are also the same as those accepted
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 // by oopDesc::field_base.
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 // 32-bit machines ignore the high half of long offsets
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 Node* adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2893
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2894 // For CAS, unlike inline_unsafe_access, there seems no point in
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2895 // trying to refine types. Just use the coarse types here.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 const Type *value_type = Type::get_const_basic_type(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 Compile::AliasType* alias_type = C->alias_type(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2899
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2900 if (kind == LS_xchg && type == T_OBJECT) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2901 const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2902 if (tjp != NULL) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2903 value_type = tjp;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2904 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2905 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2906
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 int alias_idx = C->get_alias_index(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2908
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2909 // Memory-model-wise, a LoadStore acts like a little synchronized
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2910 // block, so needs barriers on each side. These don't translate
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2911 // into actual barriers on most machines, but we still need rest of
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 // compiler to respect ordering.
a61af66fc99e Initial load
duke
parents:
diff changeset
2913
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 // 4984716: MemBars must be inserted before this
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 // memory node in order to avoid a false
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 // dependency which will confuse the scheduler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 Node *mem = memory(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2921
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 // For now, we handle only those cases that actually exist: ints,
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 // longs, and Object. Adding others should be straightforward.
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2924 Node* load_store;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 switch(type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 case T_INT:
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2927 if (kind == LS_xadd) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2928 load_store = _gvn.transform(new (C) GetAndAddINode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2929 } else if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2930 load_store = _gvn.transform(new (C) GetAndSetINode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2931 } else if (kind == LS_cmpxchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2932 load_store = _gvn.transform(new (C) CompareAndSwapINode(control(), mem, adr, newval, oldval));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2933 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2934 ShouldNotReachHere();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2935 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 case T_LONG:
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2938 if (kind == LS_xadd) {
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) GetAndAddLNode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2940 } else if (kind == LS_xchg) {
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) GetAndSetLNode(control(), mem, adr, newval, adr_type));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2942 } else if (kind == LS_cmpxchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2943 load_store = _gvn.transform(new (C) CompareAndSwapLNode(control(), mem, adr, newval, oldval));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2944 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2945 ShouldNotReachHere();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2946 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 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
2949 // 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
2950 // 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
2951 // 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
2952 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
2953 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
2954
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4778
diff changeset
2955 // Reference stores need a store barrier.
12169
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2956 if (kind == LS_xchg) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2957 // 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
2958 if (!can_move_pre_barrier()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2959 pre_barrier(true /* do_load*/,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2960 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
2961 NULL /* pre_val*/,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2962 T_OBJECT);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2963 } // 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
2964 } else if (kind == LS_cmpxchg) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2965 // Same as for newval above:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2966 if (_gvn.type(oldval) == TypePtr::NULL_PTR) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2967 oldval = _gvn.makecon(TypePtr::NULL_PTR);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2968 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2969 // 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
2970 pre_barrier(false /* do_load */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2971 control(), NULL, NULL, max_juint, NULL, NULL,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2972 oldval /* pre_val */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2973 T_OBJECT);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2974 } else {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2975 ShouldNotReachHere();
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2976 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
2977
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
2978 #ifdef _LP64
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
2979 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
2980 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
2981 if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2982 load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr,
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2983 newval_enc, adr_type, value_type->make_narrowoop()));
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2984 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2985 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
2986 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
2987 load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr,
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2988 newval_enc, oldval_enc));
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2989 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
2990 } else
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
2991 #endif
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 174
diff changeset
2992 {
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2993 if (kind == LS_xchg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
2994 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
2995 } else {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2996 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
2997 load_store = _gvn.transform(new (C) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
2998 }
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 174
diff changeset
2999 }
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3000 post_barrier(control(), load_store, base, adr, alias_idx, newval, T_OBJECT, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3003 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3006
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3007 // SCMemProjNodes represent the memory state of a LoadStore. Their
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3008 // main role is to prevent LoadStore nodes from being optimized away
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3009 // when their results aren't used.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3010 Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 set_memory(proj, alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3012
12169
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3013 if (type == T_OBJECT && kind == LS_xchg) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3014 #ifdef _LP64
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3015 if (adr->bottom_type()->is_ptr_to_narrowoop()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3016 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
3017 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3018 #endif
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3019 if (can_move_pre_barrier()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3020 // 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
3021 // 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
3022 // gets inserted between them.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3023 pre_barrier(false /* do_load */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3024 control(), NULL, NULL, max_juint, NULL, NULL,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3025 load_store /* pre_val */,
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3026 T_OBJECT);
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3027 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3028 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12078
diff changeset
3029
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 // Add the trailing membar surrounding the access
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 insert_mem_bar(Op_MemBarAcquire);
a61af66fc99e Initial load
duke
parents:
diff changeset
3033
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3034 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
3035 set_result(load_store);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3038
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3039 //----------------------------inline_unsafe_ordered_store----------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3040 // 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
3041 // 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
3042 // public native void sun.misc.Unsafe.putOrderedLong(Object o, long offset, long x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 // This is another variant of inline_unsafe_access, differing in
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 // that it always issues store-store ("release") barrier and ensures
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 // store-atomicity (which only matters for "long").
a61af66fc99e Initial load
duke
parents:
diff changeset
3047
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 if (callee()->is_static()) return false; // caller must have the capability!
a61af66fc99e Initial load
duke
parents:
diff changeset
3049
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 // Check the signatures.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3054 ciSignature* sig = callee()->signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 BasicType rtype = sig->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 assert(rtype == T_VOID, "must return void");
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 assert(sig->count() == 3, "has 3 arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 assert(sig->type_at(0)->basic_type() == T_OBJECT, "base is object");
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 assert(sig->type_at(1)->basic_type() == T_LONG, "offset is long");
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3064
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
3066
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3067 // Get arguments:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3068 Node* receiver = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3069 Node* base = argument(1); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3070 Node* offset = argument(2); // type: long
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3071 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
3072
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3073 // Null check receiver.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3074 receiver = null_check(receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3078
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 // Build field offset expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 // 32-bit machines ignore the high half of long offsets
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 offset = ConvL2X(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 Node* adr = make_unsafe_address(base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 const Type *value_type = Type::get_const_basic_type(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 Compile::AliasType* alias_type = C->alias_type(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3087
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // 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
3091 const bool require_atomic_access = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 Node* store;
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 if (type == T_OBJECT) // reference stores need a store barrier.
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 787
diff changeset
3094 store = store_oop_to_unknown(control(), base, adr, adr_type, val, type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access);
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3101
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3102 bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3103 // 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
3104 // then issue acquire, release, or volatile mem_bar.
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3105 insert_mem_bar(Op_MemBarCPUOrder);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3106 switch(id) {
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3107 case vmIntrinsics::_loadFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3108 insert_mem_bar(Op_MemBarAcquire);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3109 return true;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3110 case vmIntrinsics::_storeFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3111 insert_mem_bar(Op_MemBarRelease);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3112 return true;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3113 case vmIntrinsics::_fullFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3114 insert_mem_bar(Op_MemBarVolatile);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3115 return true;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3116 default:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3117 fatal_unexpected_iid(id);
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3118 return false;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3119 }
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3120 }
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 7423
diff changeset
3121
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3122 bool LibraryCallKit::klass_needs_init_guard(Node* kls) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3123 if (!kls->is_Con()) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3124 return true;
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3125 }
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3126 const TypeKlassPtr* klsptr = kls->bottom_type()->isa_klassptr();
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3127 if (klsptr == NULL) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3128 return true;
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3129 }
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3130 ciInstanceKlass* ik = klsptr->klass()->as_instance_klass();
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3131 // don't need a guard for a klass that is already initialized
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3132 return !ik->is_initialized();
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3133 }
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3134
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3135 //----------------------------inline_unsafe_allocate---------------------------
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3136 // public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 bool LibraryCallKit::inline_unsafe_allocate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 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
3139
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3140 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
3141 Node* cls = null_check(argument(1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3143
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3144 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
3145 kls = null_check(kls);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 if (stopped()) return true; // argument was like int.class
a61af66fc99e Initial load
duke
parents:
diff changeset
3147
12078
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3148 Node* test = NULL;
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3149 if (LibraryCallKit::klass_needs_init_guard(kls)) {
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3150 // Note: The argument might still be an illegal value like
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3151 // Serializable.class or Object[].class. The runtime will handle it.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3152 // But we must make an explicit check for initialization.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3153 Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3154 // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3155 // can generate code to load it as unsigned byte.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3156 Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3157 Node* bits = intcon(InstanceKlass::fully_initialized);
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3158 test = _gvn.transform(new (C) SubINode(inst, bits));
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3159 // The 'test' is non-zero if we need to take a slow path.
acedd49a1bce 8022675: Redundant class init check
rbackman
parents: 11080
diff changeset
3160 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3161
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 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
3163 set_result(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3166
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3167 #ifdef TRACE_HAVE_INTRINSICS
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3168 /*
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3169 * oop -> myklass
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3170 * myklass->trace_id |= USED
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3171 * return myklass->trace_id & ~0x3
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3172 */
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3173 bool LibraryCallKit::inline_native_classID() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3174 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
3175 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
3176 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
3177 kls = null_check(kls, T_OBJECT);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3178 ByteSize offset = TRACE_ID_OFFSET;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3179 Node* insp = basic_plus_adr(kls, in_bytes(offset));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3180 Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3181 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
3182 Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits));
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3183 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
3184 Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused));
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3185
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3186 const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3187 store_to_memory(control(), insp, orl, T_LONG, adr_type);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3188 set_result(andl);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3189 return true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3190 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3191
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3192 bool LibraryCallKit::inline_native_threadID() {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3193 Node* tls_ptr = NULL;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3194 Node* cur_thr = generate_current_thread(tls_ptr);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3195 Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3196 Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3197 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
3198
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3199 Node* threadid = NULL;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3200 size_t thread_id_size = OSThread::thread_id_size();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3201 if (thread_id_size == (size_t) BytesPerLong) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3202 threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3203 } else if (thread_id_size == (size_t) BytesPerInt) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3204 threadid = make_load(control(), p, TypeInt::INT, T_INT);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3205 } else {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3206 ShouldNotReachHere();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3207 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3208 set_result(threadid);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3209 return true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3210 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3211 #endif
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3212
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 //------------------------inline_native_time_funcs--------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 // inline code for System.currentTimeMillis() and System.nanoTime()
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 // these have the same type and signature
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5934
diff changeset
3216 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
3217 const TypeFunc* tf = OptoRuntime::void_long_Type();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 const TypePtr* no_memory_effects = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 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
3220 Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 #ifdef ASSERT
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3222 Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 assert(value_top == top(), "second value must be top");
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 #endif
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3225 set_result(value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3228
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 //------------------------inline_native_currentThread------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 bool LibraryCallKit::inline_native_currentThread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 Node* junk = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3232 set_result(generate_current_thread(junk));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3235
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 //------------------------inline_native_isInterrupted------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3237 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 bool LibraryCallKit::inline_native_isInterrupted() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 // Add a fast path to t.isInterrupted(clear_int):
17716
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3240 // (t == Thread.current() &&
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3241 // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 // So, in the common case that the interrupt bit is false,
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 // we avoid making a call into the VM. Even if the interrupt bit
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 // is true, if the clear_int argument is false, we avoid the VM call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 // However, if the receiver is not currentThread, we must call the VM,
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 // because there must be some locking done around the operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3248
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 // We only go to the fast case code if we pass two guards.
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 // 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
3251
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3252 enum {
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3253 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
3254 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
3255 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
3256 PATH_LIMIT
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3257 };
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3258
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3259 // 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
3260 // out of the function.
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3261 insert_mem_bar(Op_MemBarCPUOrder);
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3262
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3263 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
3264 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
3265
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3266 RegionNode* slow_region = new (C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3268
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 // (a) Receiving thread must be the current thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 Node* rec_thr = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 Node* tls_ptr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 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
3273 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
3274 Node* bol_thr = _gvn.transform(new (C) BoolNode(cmp_thr, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3275
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3276 generate_slow_guard(bol_thr, slow_region);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3277
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 // (b) Interrupt bit on TLS must be false.
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS);
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 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
3282
787
aabd393cf1ee 6772683: Thread.isInterrupted() fails to return true on multiprocessor PC
kvn
parents: 775
diff changeset
3283 // Set the control input on the field _interrupted read to prevent it floating up.
aabd393cf1ee 6772683: Thread.isInterrupted() fails to return true on multiprocessor PC
kvn
parents: 775
diff changeset
3284 Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3285 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
3286 Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3287
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
3289
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 // 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
3291 Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 result_rgn->init_req(no_int_result_path, false_bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 result_val->init_req(no_int_result_path, intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3294
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 // drop through to next case
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3296 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3297
17716
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3298 #ifndef TARGET_OS_FAMILY_windows
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 Node* clr_arg = argument(1);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3301 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
3302 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
3304
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 // 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
3306 Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 result_rgn->init_req(no_clear_result_path, false_arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 result_val->init_req(no_clear_result_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3309
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 // drop through to next case
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3311 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
17716
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3312 #else
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3313 // To return true on Windows you must read the _interrupted field
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3314 // and check the the event state i.e. take the slow path.
cdb71841f4bc 6498581: ThreadInterruptTest3 produces wrong output on Windows
minqi
parents: 17670
diff changeset
3315 #endif // TARGET_OS_FAMILY_windows
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3316
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 // (d) Otherwise, go to the slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 slow_region->add_req(control());
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3319 set_control( _gvn.transform(slow_region));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3320
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 // There is no slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 result_rgn->init_req(slow_result_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 result_val->init_req(slow_result_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 // non-virtual because it is a private non-static
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_isInterrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
3328
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 Node* slow_val = set_results_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 // this->control() comes from set_results_for_java_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3331
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 Node* fast_io = slow_call->in(TypeFunc::I_O);
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 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
3334
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 // 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
3336 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
3337 PhiNode* result_io = PhiNode::make(result_rgn, fast_io, Type::ABIO);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3338
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 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
3340 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
3341 result_mem->init_req(slow_result_path, reset_memory());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 result_val->init_req(slow_result_path, slow_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
3343
7422
eb409f2f146e 8003135: HotSpot inlines and hoists the Thread.currentThread().isInterrupted() out of the loop
vlivanov
parents: 7200
diff changeset
3344 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
3345 set_i_o( _gvn.transform(result_io));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3347
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 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
3349 set_result(result_rgn, result_val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3352
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 //---------------------------load_mirror_from_klass----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 // Given a klass oop, load its java mirror (a java.lang.Class oop).
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 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
3356 Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 return make_load(NULL, p, TypeInstPtr::MIRROR, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3359
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 //-----------------------load_klass_from_mirror_common-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 // Given a java mirror (a java.lang.Class oop), load its corresponding klass oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 // Test the klass oop for null (signifying a primitive Class like Integer.TYPE),
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 // and branch to the given path on the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 // If never_see_null, take an uncommon trap on null, so we can optimistically
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 // compile for the non-null case.
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 // If the region is NULL, force never_see_null = true.
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror,
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 bool never_see_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 int null_path,
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 if (region == NULL) never_see_null = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 Node* p = basic_plus_adr(mirror, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 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
3375 Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 kls = null_check_oop(kls, &null_ctl, never_see_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 if (region != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 // Set region->in(null_path) if the mirror is a primitive (e.g, int.class).
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 region->init_req(null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 assert(null_ctl == top(), "no loose ends");
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 return kls;
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3386
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 //--------------------(inline_native_Class_query helpers)---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 // Use this for JVM_ACC_INTERFACE, JVM_ACC_IS_CLONEABLE, JVM_ACC_HAS_FINALIZER.
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 // Fall through if (mods & mask) == bits, take the guard otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 // Branch around if the given klass has the given modifier bit set.
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 // 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
3393 Node* modp = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 Node* mask = intcon(modifier_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 Node* bits = intcon(modifier_bits);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3397 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
3398 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
3399 Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 return generate_fair_guard(bol, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 return generate_access_flags_guard(kls, JVM_ACC_INTERFACE, 0, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3405
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 //-------------------------inline_native_Class_query-------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 const Type* return_type = TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 Node* prim_return_value = top(); // what happens if it's a primitive class?
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 bool expect_prim = false; // most of these guys expect to work on refs
a61af66fc99e Initial load
duke
parents:
diff changeset
3412
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 enum { _normal_path = 1, _prim_path = 2, PATH_LIMIT };
a61af66fc99e Initial load
duke
parents:
diff changeset
3414
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3415 Node* mirror = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3416 Node* obj = top();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3417
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 case vmIntrinsics::_isInstance:
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 // nothing is an instance of a primitive type
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 prim_return_value = intcon(0);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3422 obj = argument(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 case vmIntrinsics::_getModifiers:
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line");
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin);
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 case vmIntrinsics::_isInterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 prim_return_value = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 case vmIntrinsics::_isArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 prim_return_value = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 expect_prim = true; // cf. ObjectStreamClass.getClassSignature
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 case vmIntrinsics::_isPrimitive:
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 prim_return_value = intcon(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 expect_prim = true; // obviously
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 case vmIntrinsics::_getSuperclass:
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 prim_return_value = null();
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 case vmIntrinsics::_getComponentType:
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 prim_return_value = null();
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 case vmIntrinsics::_getClassAccessFlags:
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 return_type = TypeInt::INT; // not bool! 6297094
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3453 fatal_unexpected_iid(id);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3454 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3456
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 if (mirror_con == NULL) return false; // cannot happen?
a61af66fc99e Initial load
duke
parents:
diff changeset
3459
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
3461 if (C->print_intrinsics() || C->print_inlining()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 ciType* k = mirror_con->java_mirror_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 if (k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 k->print_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3470
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 // 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
3472 RegionNode* region = new (C) RegionNode(PATH_LIMIT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 record_for_igvn(region);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3474 PhiNode* phi = new (C) PhiNode(region, return_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3475
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 // The mirror will never be null of Reflection.getClassAccessFlags, however
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 // if it is. See bug 4774291.
a61af66fc99e Initial load
duke
parents:
diff changeset
3479
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 // For Reflection.getClassAccessFlags(), the null check occurs in
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 // the wrong place; see inline_unsafe_access(), above, for a similar
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 // situation.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3483 mirror = null_check(mirror);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 // If mirror or obj is dead, only null-path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3486
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 if (expect_prim) never_see_null = false; // expect nulls (meaning prims)
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 // Now load the mirror's klass metaobject, and null-check it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 // 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
3491 Node* kls = load_klass_from_mirror(mirror, never_see_null, region, _prim_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 // If kls is null, we have a primitive mirror.
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 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
3494 if (stopped()) { set_result(region, phi); return true; }
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3495 bool safe_for_replace = (region->in(_prim_path) == top());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3496
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 Node* p; // handy temp
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 Node* null_ctl;
a61af66fc99e Initial load
duke
parents:
diff changeset
3499
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 // Now that we have the non-null klass, we can perform the real query.
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 // For constant classes, the query will constant-fold in LoadNode::Value.
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 Node* query_value = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 case vmIntrinsics::_isInstance:
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 // nothing is an instance of a primitive type
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3506 query_value = gen_instanceof(obj, kls, safe_for_replace);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3508
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 case vmIntrinsics::_getModifiers:
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3510 p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 query_value = make_load(NULL, p, TypeInt::INT, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3513
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 case vmIntrinsics::_isInterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // (To verify this code sequence, check the asserts in JVM_IsInterface.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 if (generate_interface_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 // A guard was added. If the guard is taken, it was an interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 phi->add_req(intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 // If we fall through, it's a plain class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 query_value = intcon(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::_isArray:
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 // (To verify this code sequence, check the asserts in JVM_IsArrayClass.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 if (generate_array_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 // A guard was added. If the guard is taken, it was an array.
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::_isPrimitive:
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 query_value = intcon(0); // "normal" path produces false
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3535
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 case vmIntrinsics::_getSuperclass:
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 // The rules here are somewhat unfortunate, but we can still do better
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 // with random logic than with a JNI call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 // Interfaces store null or Object as _super, but must report null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 // Arrays store an intermediate super as _super, but must report Object.
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 // Other types can report the actual _super.
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 // (To verify this code sequence, check the asserts in JVM_IsInterface.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 if (generate_interface_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // A guard was added. If the guard is taken, it was an interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 phi->add_req(null());
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 if (generate_array_guard(kls, region) != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 // A guard was added. If the guard is taken, it was an array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 // 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
3550 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
3551 kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 kls = null_check_oop(kls, &null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 if (null_ctl != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 // If the guard is taken, Object.superClass is null (both klass and mirror).
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 region->add_req(null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 phi ->add_req(null());
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 query_value = load_mirror_from_klass(kls);
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3563
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 case vmIntrinsics::_getComponentType:
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 if (generate_array_guard(kls, region) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 // Be sure to pin the oop load to the guard edge just created:
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 Node* is_array_ctrl = region->in(region->req()-1);
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6804
diff changeset
3568 Node* cma = basic_plus_adr(kls, in_bytes(ArrayKlass::component_mirror_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 Node* cmo = make_load(is_array_ctrl, cma, TypeInstPtr::MIRROR, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 phi->add_req(cmo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 query_value = null(); // non-array case is null
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3574
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 case vmIntrinsics::_getClassAccessFlags:
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3961
diff changeset
3576 p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 query_value = make_load(NULL, p, TypeInt::INT, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3579
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3581 fatal_unexpected_iid(id);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3582 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3584
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 // Fall-through is the normal case of a query to a real class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 phi->init_req(1, query_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 region->init_req(1, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3588
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 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
3590 set_result(region, phi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3593
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 //--------------------------inline_native_subtype_check------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 // This intrinsic takes the JNI calls out of the heart of
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 // UnsafeFieldAccessorImpl.set, which improves Field.set, readObject, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 bool LibraryCallKit::inline_native_subtype_check() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 // Pull both arguments off the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 Node* args[2]; // two java.lang.Class mirrors: superc, subc
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 args[0] = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 args[1] = argument(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 Node* klasses[2]; // corresponding Klasses: superk, subk
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 klasses[0] = klasses[1] = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3604
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 // A full decision tree on {superc is prim, subc is prim}:
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 _prim_0_path = 1, // {P,N} => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 // {P,P} & superc!=subc => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 _prim_same_path, // {P,P} & superc==subc => true
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 _prim_1_path, // {N,P} => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 _ref_subtype_path, // {N,N} & subtype check wins => true
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 _both_ref_path, // {N,N} & subtype check loses => false
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 PATH_LIMIT
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3615
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3616 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
3617 Node* phi = new (C) PhiNode(region, TypeInt::BOOL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3619
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 int class_klass_offset = java_lang_Class::klass_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3623
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 // First null-check both mirrors and load each mirror's klass metaobject.
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 int which_arg;
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 for (which_arg = 0; which_arg <= 1; which_arg++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 Node* arg = args[which_arg];
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3628 arg = null_check(arg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 if (stopped()) break;
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7200
diff changeset
3630 args[which_arg] = arg;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3631
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 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
3633 Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 klasses[which_arg] = _gvn.transform(kls);
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3636
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 // Having loaded both klasses, test each for null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 for (which_arg = 0; which_arg <= 1; which_arg++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 Node* kls = klasses[which_arg];
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 kls = null_check_oop(kls, &null_ctl, never_see_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 int prim_path = (which_arg == 0 ? _prim_0_path : _prim_1_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 region->init_req(prim_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 if (stopped()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 klasses[which_arg] = kls;
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3648
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 // now we have two reference types, in klasses[0..1]
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 Node* subk = klasses[1]; // the argument to isAssignableFrom
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 Node* superk = klasses[0]; // the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 region->set_req(_both_ref_path, gen_subtype_check(subk, superk));
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 // now we have a successful reference subtype check
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 region->set_req(_ref_subtype_path, control());
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 both operands are primitive (both klasses null), then
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 // we must return true when they are identical primitives.
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 // It is convenient to test this after the first null klass check.
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 set_control(region->in(_prim_0_path)); // go back to first null check
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 // 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
3664 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
3665 Node* bol_eq = _gvn.transform(new (C) BoolNode(cmp_eq, BoolTest::eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 generate_guard(bol_eq, region, PROB_FAIR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 if (region->req() == PATH_LIMIT+1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // A guard was added. If the added guard is taken, superc==subc.
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 region->swap_edges(PATH_LIMIT, _prim_same_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 region->del_req(PATH_LIMIT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 region->set_req(_prim_0_path, control()); // Not equal after all.
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3674
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // these are the only paths that produce 'true':
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 phi->set_req(_prim_same_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 phi->set_req(_ref_subtype_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
3678
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // pull together the cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 assert(region->req() == PATH_LIMIT, "sane region");
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 for (uint i = 1; i < region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 Node* ctl = region->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 if (ctl == NULL || ctl == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 region->set_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 phi ->set_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 } else if (phi->in(i) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 phi->set_req(i, intcon(0)); // all other paths produce 'false'
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3690
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 set_control(_gvn.transform(region));
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3692 set_result(_gvn.transform(phi));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3695
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 //---------------------generate_array_guard_common------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region,
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 bool obj_array, bool not_array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 // If obj_array/non_array==false/false:
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 // Branch around if the given klass is in fact an array (either obj or prim).
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 // If obj_array/non_array==false/true:
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 // Branch around if the given klass is not an array klass of any kind.
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 // If obj_array/non_array==true/true:
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 // Branch around if the kls is not an oop array (kls is int[], String, etc.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 // If obj_array/non_array==true/false:
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 // Branch around if the kls is an oop array (Object[] or subtype)
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // Like generate_guard, adds a new path onto the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 jint layout_con = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 Node* layout_val = get_layout_helper(kls, layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 if (layout_val == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 bool query = (obj_array
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 ? Klass::layout_helper_is_objArray(layout_con)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3714 : Klass::layout_helper_is_array(layout_con));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 if (query == not_array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 return NULL; // never a branch
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 } else { // always a branch
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 Node* always_branch = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 if (region != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 region->add_req(always_branch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 return always_branch;
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 // Now test the correct condition.
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 jint nval = (obj_array
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 ? ((jint)Klass::_lh_array_tag_type_value
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 << Klass::_lh_array_tag_shift)
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 : Klass::_lh_neutral_value);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
3730 Node* cmp = _gvn.transform(new(C) CmpINode(layout_val, intcon(nval)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 // invert the test if we are looking for a non-array
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 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
3734 Node* bol = _gvn.transform(new(C) BoolNode(cmp, btest));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 return generate_fair_guard(bol, region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3737
a61af66fc99e Initial load
duke
parents:
diff changeset
3738
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 //-----------------------inline_native_newArray--------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3740 // private static native Object java.lang.reflect.newArray(Class<?> componentType, int length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 bool LibraryCallKit::inline_native_newArray() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 Node* mirror = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3743 Node* count_val = argument(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3744
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3745 mirror = null_check(mirror);
163
885ed790ecf0 6695810: null oop passed to encode_heap_oop_not_null
kvn
parents: 113
diff changeset
3746 // 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
3747 if (stopped()) return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3748
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 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
3750 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
3751 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
3752 TypeInstPtr::NOTNULL);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3753 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
3754 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
3755 TypePtr::BOTTOM);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3756
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 result_reg, _slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 Node* normal_ctl = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 Node* no_array_ctl = result_reg->in(_slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
3762
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 // Generate code for the slow case. We make a call to newArray().
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 set_control(no_array_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 // Either the input type is void.class, or else the
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 // array klass has not yet been cached. Either the
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 // ensuing call will throw an exception, or else it
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 // will cache the array klass for next time.
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 CallJavaNode* slow_call = generate_method_call_static(vmIntrinsics::_newArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 Node* slow_result = set_results_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 // this->control() comes from set_results_for_java_call
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 result_reg->set_req(_slow_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 result_val->set_req(_slow_path, slow_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 result_io ->set_req(_slow_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 result_mem->set_req(_slow_path, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3779
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 set_control(normal_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 // Normal case: The array type has been cached in the java.lang.Class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 // The following call works fine even if the array type is polymorphic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 // 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
3785 Node* obj = new_array(klass_node, count_val, 0); // no arguments to push
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 result_reg->init_req(_normal_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 result_val->init_req(_normal_path, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 result_io ->init_req(_normal_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 result_mem->init_req(_normal_path, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3791
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 // Return the combined state.
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 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
3794 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
3795
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 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
3797 set_result(result_reg, result_val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3800
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 //----------------------inline_native_getLength--------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3802 // public static native int java.lang.reflect.Array.getLength(Object array);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 bool LibraryCallKit::inline_native_getLength() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3805
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3806 Node* array = null_check(argument(0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 // If array is dead, only null-path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3809
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 // Deoptimize if it is a non-array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 Node* non_array = generate_non_array_guard(load_object_klass(array), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3812
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 if (non_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 set_control(non_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 uncommon_trap(Deoptimization::Reason_intrinsic,
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 Deoptimization::Action_maybe_recompile);
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3819
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 // If control is dead, only non-array-path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3822
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 // The works fine even if the array type is polymorphic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 // 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
3825 Node* result = load_array_length(array);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3826
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3827 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
3828 set_result(result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3831
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 //------------------------inline_array_copyOf----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3833 // 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
3834 // 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
3835 bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3837
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3838 // Get the arguments.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 Node* original = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3840 Node* start = is_copyOfRange? argument(1): intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 Node* end = is_copyOfRange? argument(2): argument(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 Node* array_type_mirror = is_copyOfRange? argument(3): argument(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3843
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3844 Node* newcopy;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3845
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3846 // 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
3847 // 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
3848 { PreserveReexecuteState preexecs(this);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3849 jvms()->set_should_reexecute(true);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3850
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3851 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
3852 original = null_check(original);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3853
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3854 // Check if a null path was taken unconditionally.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3855 if (stopped()) return true;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3856
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3857 Node* orig_length = load_array_length(original);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3858
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3859 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
3860 klass_node = null_check(klass_node);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3861
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3862 RegionNode* bailout = new (C) RegionNode(1);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3863 record_for_igvn(bailout);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3864
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3865 // 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
3866 // Bail out if that is so.
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3867 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
3868 if (not_objArray != NULL) {
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3869 // 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
3870 ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3871 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
3872 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
3873 cast->init_req(0, control());
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3874 klass_node = _gvn.transform(cast);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3875 }
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3876
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3877 // 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
3878 generate_negative_guard(start, bailout, &start);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3879 generate_negative_guard(end, bailout, &end);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3880
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3881 Node* length = end;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3882 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
3883 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
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 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
3887 // 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
3888 // 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
3889 // should be thrown
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3890 generate_negative_guard(length, bailout, &length);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3891
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3892 if (bailout->req() > 1) {
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3893 PreserveJVMState pjvms(this);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3894 set_control(_gvn.transform(bailout));
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3895 uncommon_trap(Deoptimization::Reason_intrinsic,
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3896 Deoptimization::Action_maybe_recompile);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3897 }
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3898
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3899 if (!stopped()) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3900 // 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
3901 // 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
3902 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
3903 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
3904
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3905 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
3906
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3907 // 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
3908 // 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
3909 // oop stores need checking.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3910 // 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
3911 // 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
3912 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
3913 // 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
3914 // negative.
eeb819cf36e5 7174363: Arrays.copyOfRange leads to VM crash with -Xcomp -server if executed by testing framework
roland
parents: 6143
diff changeset
3915 bool length_never_negative = !is_copyOfRange;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3916 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3917 original, start, newcopy, intcon(0), moved,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
3918 disjoint_bases, length_never_negative);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
3919 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3920 } // original reexecute is set back here
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3921
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 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
3923 if (!stopped()) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3924 set_result(newcopy);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3925 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3928
a61af66fc99e Initial load
duke
parents:
diff changeset
3929
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 //----------------------generate_virtual_guard---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 // Helper for hashCode and clone. Peeks inside the vtable to avoid a call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 RegionNode* slow_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 ciMethod* method = callee();
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 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
3936 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
3937 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
3938 // 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
3939 int entry_offset = (InstanceKlass::vtable_start_offset() +
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 vtable_index*vtableEntry::size()) * wordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 vtableEntry::method_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 Node* entry_addr = basic_plus_adr(obj_klass, entry_offset);
6888
cfe522e6461c 8000623: tools/javac/Diagnostics/6769027/T6769027.java crashes in PSPromotionManager::copy_to_survivor_space
kvn
parents: 6853
diff changeset
3943 Node* target_call = make_load(NULL, entry_addr, TypePtr::NOTNULL, T_ADDRESS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3944
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 // 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
3946 const TypePtr* native_call_addr = TypeMetadataPtr::make(method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3947
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 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
3949 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
3950 Node* test_native = _gvn.transform(new(C) BoolNode(chk_native, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3951
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 return generate_slow_guard(test_native, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3954
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 //-----------------------generate_method_call----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 // Use generate_method_call to make a slow-call to the real
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 // method if the fast path fails. An alternative would be to
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 // use a stub like OptoRuntime::slow_arraycopy_Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 // This only works for expanding the current library call,
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 // not another intrinsic. (E.g., don't use this for making an
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 // arraycopy call inside of the copyOf intrinsic.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 CallJavaNode*
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 // When compiling the intrinsic method itself, do not use this technique.
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 guarantee(callee() != C->method(), "cannot make slow-call to self");
a61af66fc99e Initial load
duke
parents:
diff changeset
3966
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 ciMethod* method = callee();
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 // ensure the JVMS we have will be correct for this call
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 guarantee(method_id == method->intrinsic_id(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
3970
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 const TypeFunc* tf = TypeFunc::make(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 CallJavaNode* slow_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 if (is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 assert(!is_virtual, "");
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10120
diff changeset
3975 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
3976 SharedRuntime::get_resolve_static_call_stub(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3977 method, bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 } else if (is_virtual) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
3979 null_check_receiver();
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
3980 int vtable_index = Method::invalid_vtable_index;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 if (UseInlineCaches) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 // Suppress the vtable call
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 // hashCode and clone are not a miranda methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 // so the vtable index is fixed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 // No need to use the linkResolver to get it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 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
3988 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
3989 err_msg_res("bad index %d", vtable_index));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3991 slow_call = new(C) CallDynamicJavaNode(tf,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3992 SharedRuntime::get_resolve_virtual_call_stub(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
3993 method, vtable_index, bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 } 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
3995 null_check_receiver();
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10120
diff changeset
3996 slow_call = new(C) CallStaticJavaNode(C, tf,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 SharedRuntime::get_resolve_opt_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 method, bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 slow_call->set_optimized_virtual(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 set_arguments_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 set_edges_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 return slow_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4005
a61af66fc99e Initial load
duke
parents:
diff changeset
4006
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 //------------------------------inline_native_hashcode--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 // Build special case code for calls to hashCode on an object.
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 assert(is_static == callee()->is_static(), "correct intrinsic selection");
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 assert(!(is_virtual && is_static), "either virtual, special, or static");
a61af66fc99e Initial load
duke
parents:
diff changeset
4012
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT };
a61af66fc99e Initial load
duke
parents:
diff changeset
4014
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4015 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
4016 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
4017 TypeInt::INT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4018 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
4019 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
4020 TypePtr::BOTTOM);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 Node* obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 if (!is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 // Check for hashing null object
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4024 obj = null_check_receiver();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 if (stopped()) return true; // unconditionally null
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 result_reg->init_req(_null_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 result_val->init_req(_null_path, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 // Do a null check, and return zero if null.
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 // System.identityHashCode(null) == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 obj = argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 obj = null_check_oop(obj, &null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 result_reg->init_req(_null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 result_val->init_req(_null_path, _gvn.intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4037
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 // Unconditionally null? Then return right away.
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 if (stopped()) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4040 set_control( result_reg->in(_null_path));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 if (!stopped())
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4042 set_result(result_val->in(_null_path));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4045
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 // After null check, get the object's klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 Node* obj_klass = load_object_klass(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
4048
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 // This call may be virtual (invokevirtual) or bound (invokespecial).
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 // For each case we generate slightly different code.
a61af66fc99e Initial load
duke
parents:
diff changeset
4051
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 // We only go to the fast case code if we pass a number of guards. The
a61af66fc99e Initial load
duke
parents:
diff changeset
4053 // 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
4054 RegionNode* slow_region = new (C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4056
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 // If this is a virtual call, we generate a funny guard. We pull out
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 // the vtable entry corresponding to hashCode() from the target object.
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 // If the target method which we are calling happens to be the native
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 // Object hashCode() method, we pass the guard. We do not need this
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 // guard for non-virtual calls -- the caller is known to be the native
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 // Object hashCode().
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 if (is_virtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 generate_virtual_guard(obj_klass, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4066
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 // Get the header out of the object, use LoadMarkNode when available
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1552
diff changeset
4069 Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4070
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 // Test the header to see if it is unlocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 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
4073 Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 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
4075 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
4076 Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4077
a61af66fc99e Initial load
duke
parents:
diff changeset
4078 generate_slow_guard(test_unlocked, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4079
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 // Get the hash value and check to see that it has been properly assigned.
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 // We depend on hash_mask being at most 32 bits and avoid the use of
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 // vm: see markOop.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 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
4086 Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 // 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
4088 // as the shift drops the relevant bits into the low 32 bits. Note that
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 // Java spec says that HashCode is an int so there's no point in capturing
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 hshifted_header = ConvX2I(hshifted_header);
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4092 Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4093
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 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
4095 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
4096 Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4097
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 generate_slow_guard(test_assigned, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4099
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 Node* init_mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 // fill in the rest of the null path:
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 result_io ->init_req(_null_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 result_mem->init_req(_null_path, init_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4104
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 result_val->init_req(_fast_path, hash_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 result_reg->init_req(_fast_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 result_io ->init_req(_fast_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 result_mem->init_req(_fast_path, init_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4109
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 // Generate code for the slow case. We make a call to hashCode().
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 set_control(_gvn.transform(slow_region));
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 // No need for PreserveJVMState, because we're using up the present state.
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 set_all_memory(init_mem);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4115 vmIntrinsics::ID hashCode_id = is_static ? vmIntrinsics::_identityHashCode : vmIntrinsics::_hashCode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 CallJavaNode* slow_call = generate_method_call(hashCode_id, is_virtual, is_static);
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 Node* slow_result = set_results_for_java_call(slow_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 // this->control() comes from set_results_for_java_call
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 result_reg->init_req(_slow_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 result_val->init_req(_slow_path, slow_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 result_io ->set_req(_slow_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 result_mem ->set_req(_slow_path, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4124
a61af66fc99e Initial load
duke
parents:
diff changeset
4125 // Return the combined state.
a61af66fc99e Initial load
duke
parents:
diff changeset
4126 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
4127 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
4128
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4129 set_result(result_reg, result_val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4132
a61af66fc99e Initial load
duke
parents:
diff changeset
4133 //---------------------------inline_native_getClass----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4134 // 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
4135 //
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
4136 // Build special case code for calls to getClass on an object.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 bool LibraryCallKit::inline_native_getClass() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4138 Node* obj = null_check_receiver();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4139 if (stopped()) return true;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4140 set_result(load_mirror_from_klass(load_object_klass(obj)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4141 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4143
a61af66fc99e Initial load
duke
parents:
diff changeset
4144 //-----------------inline_native_Reflection_getCallerClass---------------------
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4145 // 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
4146 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 // In the presence of deep enough inlining, getCallerClass() becomes a no-op.
a61af66fc99e Initial load
duke
parents:
diff changeset
4148 //
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4149 // 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
4150 // 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
4151 // caller sensitive methods.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4154 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass");
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4158
a61af66fc99e Initial load
duke
parents:
diff changeset
4159 if (!jvms()->has_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4161 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 tty->print_cr(" Bailing out because intrinsic was inlined at top level");
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4167
a61af66fc99e Initial load
duke
parents:
diff changeset
4168 // 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
4169 // depth.
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4170 JVMState* caller_jvms = jvms();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4171
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4172 // Cf. JVM_GetCallerClass
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4173 // 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
4174 // not include the Reflection.getCallerClass() frame.
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4175 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
4176 ciMethod* m = caller_jvms->method();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4177 switch (n) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4178 case 0:
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4179 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
4180 break;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4181 case 1:
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4182 // 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
4183 if (!m->caller_sensitive()) {
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4184 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4185 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
4186 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
4187 }
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4188 #endif
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4189 return false; // bail-out; let JVM_GetCallerClass do the work
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 }
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4191 break;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4192 default:
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4193 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
4194 // 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
4195 // 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
4196 ciInstanceKlass* caller_klass = caller_jvms->method()->holder();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4197 ciInstance* caller_mirror = caller_klass->java_mirror();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4198 set_result(makecon(TypeInstPtr::make(caller_mirror)));
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4199
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4201 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
4202 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
4203 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
4204 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
4205 ciMethod* m = jvms()->of_depth(i)->method();
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4206 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
4207 }
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 #endif
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4210 return true;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4211 }
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4212 break;
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4213 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4215
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 #ifndef PRODUCT
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12269
diff changeset
4217 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
4218 tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 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
4220 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
4221 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
4222 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
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 #endif
8866
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4226
16885e702c88 7198429: need checked categorization of caller-sensitive methods in the JDK
twisti
parents: 8076
diff changeset
4227 return false; // bail-out; let JVM_GetCallerClass do the work
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4229
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 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
4231 Node* arg = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4232 Node* result;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4233
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 switch (id) {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4235 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
4236 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
4237 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
4238 case vmIntrinsics::_longBitsToDouble: result = new (C) MoveL2DNode(arg); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4239
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 case vmIntrinsics::_doubleToLongBits: {
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 // 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
4242 RegionNode *r = new (C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4243 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
4244
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4245 Node *cmpisnan = _gvn.transform(new (C) CmpDNode(arg, arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 // Build the boolean node
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4247 Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4248
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 // Branch either way.
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 // NaN case is less traveled, which makes all the difference.
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4252 Node *opt_isnan = _gvn.transform(ifisnan);
a61af66fc99e Initial load
duke
parents:
diff changeset
4253 assert( opt_isnan->is_If(), "Expect an IfNode");
a61af66fc99e Initial load
duke
parents:
diff changeset
4254 IfNode *opt_ifisnan = (IfNode*)opt_isnan;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4255 Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4256
a61af66fc99e Initial load
duke
parents:
diff changeset
4257 set_control(iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4258
a61af66fc99e Initial load
duke
parents:
diff changeset
4259 static const jlong nan_bits = CONST64(0x7ff8000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
4260 Node *slow_result = longcon(nan_bits); // return NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
4261 phi->init_req(1, _gvn.transform( slow_result ));
a61af66fc99e Initial load
duke
parents:
diff changeset
4262 r->init_req(1, iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4263
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 // Else fall through
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4265 Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4266 set_control(iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4267
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4268 phi->init_req(2, _gvn.transform(new (C) MoveD2LNode(arg)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4269 r->init_req(2, iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4270
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 // Post merge
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 set_control(_gvn.transform(r));
a61af66fc99e Initial load
duke
parents:
diff changeset
4273 record_for_igvn(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
4274
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4275 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
4276 result = phi;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4277 assert(result->bottom_type()->isa_long(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4280
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 case vmIntrinsics::_floatToIntBits: {
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 // 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
4283 RegionNode *r = new (C) RegionNode(3);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4284 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
4285
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4286 Node *cmpisnan = _gvn.transform(new (C) CmpFNode(arg, arg));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 // Build the boolean node
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4288 Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4289
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 // Branch either way.
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 // NaN case is less traveled, which makes all the difference.
a61af66fc99e Initial load
duke
parents:
diff changeset
4292 IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4293 Node *opt_isnan = _gvn.transform(ifisnan);
a61af66fc99e Initial load
duke
parents:
diff changeset
4294 assert( opt_isnan->is_If(), "Expect an IfNode");
a61af66fc99e Initial load
duke
parents:
diff changeset
4295 IfNode *opt_ifisnan = (IfNode*)opt_isnan;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4296 Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4297
a61af66fc99e Initial load
duke
parents:
diff changeset
4298 set_control(iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4299
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 static const jint nan_bits = 0x7fc00000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4301 Node *slow_result = makecon(TypeInt::make(nan_bits)); // return NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 phi->init_req(1, _gvn.transform( slow_result ));
a61af66fc99e Initial load
duke
parents:
diff changeset
4303 r->init_req(1, iftrue);
a61af66fc99e Initial load
duke
parents:
diff changeset
4304
a61af66fc99e Initial load
duke
parents:
diff changeset
4305 // Else fall through
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4306 Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 set_control(iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4308
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4309 phi->init_req(2, _gvn.transform(new (C) MoveF2INode(arg)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 r->init_req(2, iffalse);
a61af66fc99e Initial load
duke
parents:
diff changeset
4311
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 // Post merge
a61af66fc99e Initial load
duke
parents:
diff changeset
4313 set_control(_gvn.transform(r));
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 record_for_igvn(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
4315
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4316 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
4317 result = phi;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4318 assert(result->bottom_type()->isa_int(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
4319 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4321
a61af66fc99e Initial load
duke
parents:
diff changeset
4322 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4323 fatal_unexpected_iid(id);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4324 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4325 }
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4326 set_result(_gvn.transform(result));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4329
a61af66fc99e Initial load
duke
parents:
diff changeset
4330 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 #define XTOP ,top() /*additional argument*/
a61af66fc99e Initial load
duke
parents:
diff changeset
4332 #else //_LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4333 #define XTOP /*no additional argument*/
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 #endif //_LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4335
a61af66fc99e Initial load
duke
parents:
diff changeset
4336 //----------------------inline_unsafe_copyMemory-------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4337 // 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
4338 bool LibraryCallKit::inline_unsafe_copyMemory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 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
4340 null_check_receiver(); // null-check receiver
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 if (stopped()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4342
a61af66fc99e Initial load
duke
parents:
diff changeset
4343 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe".
a61af66fc99e Initial load
duke
parents:
diff changeset
4344
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4345 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
4346 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
4347 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
4348 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
4349 Node* size = ConvL2X(argument(7)); // type: long
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4350
a61af66fc99e Initial load
duke
parents:
diff changeset
4351 assert(Unsafe_field_offset_to_byte_offset(11) == 11,
a61af66fc99e Initial load
duke
parents:
diff changeset
4352 "fieldOffset must be byte-scaled");
a61af66fc99e Initial load
duke
parents:
diff changeset
4353
a61af66fc99e Initial load
duke
parents:
diff changeset
4354 Node* src = make_unsafe_address(src_ptr, src_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
4355 Node* dst = make_unsafe_address(dst_ptr, dst_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
4356
a61af66fc99e Initial load
duke
parents:
diff changeset
4357 // Conservatively insert a memory barrier on all memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
4358 // Do not let writes of the copy source or destination float below the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4359 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4360
a61af66fc99e Initial load
duke
parents:
diff changeset
4361 // Call it. Note that the length argument is not scaled.
a61af66fc99e Initial load
duke
parents:
diff changeset
4362 make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
4363 OptoRuntime::fast_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 StubRoutines::unsafe_arraycopy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4365 "unsafe_arraycopy",
a61af66fc99e Initial load
duke
parents:
diff changeset
4366 TypeRawPtr::BOTTOM,
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 src, dst, size XTOP);
a61af66fc99e Initial load
duke
parents:
diff changeset
4368
a61af66fc99e Initial load
duke
parents:
diff changeset
4369 // Do not let reads of the copy destination float above the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4371
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4374
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4375 //------------------------clone_coping-----------------------------------
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4376 // 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
4377 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
4378 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
4379 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
4380 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
4381
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4382 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
4383 if (ReduceBulkZeroing) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4384 // 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
4385 // mark Initialize node as complete.
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4386 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
4387 // 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
4388 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
4389 // 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
4390 // 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
4391 // 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
4392 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
4393 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4394
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4395 // 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
4396 // 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
4397 Node* src = obj;
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
4398 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
4399 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
4400
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4401 // 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
4402 // 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
4403 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
4404 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
4405 // base_off:
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4406 // 8 - 32-bit VM
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
4407 // 12 - 64-bit VM, compressed klass
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
4408 // 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
4409 if (base_off % BytesPerLong != 0) {
12226
7944aba7ba41 8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents: 12169
diff changeset
4410 assert(UseCompressedClassPointers, "");
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4411 if (is_array) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4412 // 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
4413 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
4414 } else {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4415 // 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
4416 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
4417 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4418 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
4419 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4420 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
4421 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
4422
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4423 // 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
4424 Node* countx = size;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4425 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
4426 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
4427
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4428 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
4429 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
4430 generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4431 src, NULL, dest, NULL, countx,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4432 /*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
4433
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4434 // 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
4435 if (card_mark) {
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4436 assert(!is_array, "");
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4437 // 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
4438 // 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
4439 // 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
4440 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
4441 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
4442 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
4443 post_barrier(control(),
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4444 memory(raw_adr_type),
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
4445 alloc_obj,
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4446 no_particular_field,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4447 raw_adr_idx,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4448 no_particular_value,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4449 T_OBJECT,
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4450 false);
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4451 }
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4452
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
4453 // 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
4454 if (alloc != NULL) {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4455 // 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
4456 // 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
4457 // other threads.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4458 // 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
4459 // 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
4460 // AllocateNode and eliminate the MemBarStoreStoreNode if possible
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4461 // 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
4462 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
4463 } else {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4464 insert_mem_bar(Op_MemBarCPUOrder);
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
4465 }
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4466 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4467
a61af66fc99e Initial load
duke
parents:
diff changeset
4468 //------------------------inline_native_clone----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4469 // 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
4470 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4471 // Here are the simple edge cases:
a61af66fc99e Initial load
duke
parents:
diff changeset
4472 // null receiver => normal trap
a61af66fc99e Initial load
duke
parents:
diff changeset
4473 // virtual and clone was overridden => slow path to out-of-line clone
a61af66fc99e Initial load
duke
parents:
diff changeset
4474 // not cloneable or finalizer => slow path to out-of-line Object.clone
a61af66fc99e Initial load
duke
parents:
diff changeset
4475 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4476 // The general case has two steps, allocation and copying.
a61af66fc99e Initial load
duke
parents:
diff changeset
4477 // Allocation has two cases, and uses GraphKit::new_instance or new_array.
a61af66fc99e Initial load
duke
parents:
diff changeset
4478 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4479 // Copying also has two cases, oop arrays and everything else.
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 // Oop arrays use arrayof_oop_arraycopy (same as System.arraycopy).
a61af66fc99e Initial load
duke
parents:
diff changeset
4481 // Everything else uses the tight inline loop supplied by CopyArrayNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
4482 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 // These steps fold up nicely if and when the cloned object's klass
a61af66fc99e Initial load
duke
parents:
diff changeset
4484 // can be sharply typed as an object array, a type array, or an instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4486 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
4487 PhiNode* result_val;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4488
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4489 // 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
4490 // 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
4491 { PreserveReexecuteState preexecs(this);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4492 jvms()->set_should_reexecute(true);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4493
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4494 Node* obj = null_check_receiver();
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4495 if (stopped()) return true;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4496
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4497 Node* obj_klass = load_object_klass(obj);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4498 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
4499 const TypeOopPtr* toop = ((tklass != NULL)
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4500 ? tklass->as_instance_type()
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4501 : TypeInstPtr::NOTNULL);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4502
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4503 // 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
4504 // 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
4505 insert_mem_bar(Op_MemBarCPUOrder);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4506
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4507 // paths into result_reg:
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4508 enum {
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4509 _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
4510 _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
4511 _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
4512 _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
4513 PATH_LIMIT
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4514 };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4515 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
4516 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
4517 TypeInstPtr::NOTNULL);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4518 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
4519 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
4520 TypePtr::BOTTOM);
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4521 record_for_igvn(result_reg);
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4522
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4523 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4524 int raw_adr_idx = Compile::AliasIdxRaw;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4525
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4526 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
4527 if (array_ctl != NULL) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4528 // It's an array.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4529 PreserveJVMState pjvms(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4530 set_control(array_ctl);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4531 Node* obj_length = load_array_length(obj);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4532 Node* obj_size = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4533 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
4534
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4535 if (!use_ReduceInitialCardMarks()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4536 // 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
4537 // 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
4538 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
4539 if (is_obja != NULL) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4540 PreserveJVMState pjvms2(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4541 set_control(is_obja);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4542 // 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
4543 bool disjoint_bases = true;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4544 bool length_never_negative = true;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4545 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4546 obj, intcon(0), alloc_obj, intcon(0),
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4547 obj_length,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4548 disjoint_bases, length_never_negative);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4549 result_reg->init_req(_objArray_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4550 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
4551 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
4552 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
4553 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4554 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4555 // 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
4556 // (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
4557 // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4558 // 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
4559 // simulate a fresh allocation, so that no further
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 986
diff changeset
4560 // 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
4561 // the object.)
900
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 if (!stopped()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4564 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
4565
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4566 // Present the results of the copy.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4567 result_reg->init_req(_array_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4568 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
4569 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
4570 result_mem ->set_req(_array_path, reset_memory());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4572 }
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4573
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4574 // 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
4575 // 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
4576 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
4577 record_for_igvn(slow_region);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4578 if (!stopped()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4579 // 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
4580 // 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
4581 // 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
4582 // 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
4583 // 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
4584 // 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
4585 // Object clone().
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4586 if (is_virtual) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4587 generate_virtual_guard(obj_klass, slow_region);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4588 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4589
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4590 // 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
4591 // 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
4592 // 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
4593 generate_access_flags_guard(obj_klass,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4594 // Test both conditions:
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4595 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
4596 // Must be cloneable but not finalizer:
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4597 JVM_ACC_IS_CLONEABLE,
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4598 slow_region);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4599 }
833
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4600
acba6af809c8 6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents: 827
diff changeset
4601 if (!stopped()) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4602 // 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
4603 PreserveJVMState pjvms(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4604 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
4605 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
4606
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4607 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
4608
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4609 // Present the results of the slow call.
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4610 result_reg->init_req(_instance_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4611 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
4612 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
4613 result_mem ->set_req(_instance_path, reset_memory());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4615
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4616 // 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
4617 set_control(_gvn.transform(slow_region));
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4618 if (!stopped()) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4619 PreserveJVMState pjvms(this);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4620 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
4621 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
4622 // 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
4623 result_reg->init_req(_slow_path, control());
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 896
diff changeset
4624 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
4625 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
4626 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
4627 }
902
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4628
fc2281ddce3c 6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents: 900
diff changeset
4629 // Return the combined state.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4630 set_control( _gvn.transform(result_reg));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
4631 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
4632 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
4633 } // original reexecute is set back here
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4634
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4635 set_result(_gvn.transform(result_val));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4636 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4638
a61af66fc99e Initial load
duke
parents:
diff changeset
4639 //------------------------------basictype2arraycopy----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 address LibraryCallKit::basictype2arraycopy(BasicType t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4641 Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 Node* dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4643 bool disjoint_bases,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4644 const char* &name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4645 bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 const TypeInt* src_offset_inttype = gvn().find_int_type(src_offset);;
a61af66fc99e Initial load
duke
parents:
diff changeset
4647 const TypeInt* dest_offset_inttype = gvn().find_int_type(dest_offset);;
a61af66fc99e Initial load
duke
parents:
diff changeset
4648
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 bool aligned = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4650 bool disjoint = disjoint_bases;
a61af66fc99e Initial load
duke
parents:
diff changeset
4651
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 // if the offsets are the same, we can treat the memory regions as
a61af66fc99e Initial load
duke
parents:
diff changeset
4653 // disjoint, because either the memory regions are in different arrays,
a61af66fc99e Initial load
duke
parents:
diff changeset
4654 // or they are identical (which we can treat as disjoint.) We can also
a61af66fc99e Initial load
duke
parents:
diff changeset
4655 // treat a copy with a destination index less that the source index
a61af66fc99e Initial load
duke
parents:
diff changeset
4656 // as disjoint since a low->high copy will work correctly in this case.
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 if (src_offset_inttype != NULL && src_offset_inttype->is_con() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4658 dest_offset_inttype != NULL && dest_offset_inttype->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 // both indices are constants
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 int s_offs = src_offset_inttype->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 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
4662 int element_size = type2aelembytes(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4663 aligned = ((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4665 if (s_offs >= d_offs) disjoint = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 } else if (src_offset == dest_offset && src_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4667 // This can occur if the offsets are identical non-constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 disjoint = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4670
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2444
diff changeset
4671 return StubRoutines::select_arraycopy_function(t, aligned, disjoint, name, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4673
a61af66fc99e Initial load
duke
parents:
diff changeset
4674
a61af66fc99e Initial load
duke
parents:
diff changeset
4675 //------------------------------inline_arraycopy-----------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4676 // 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
4677 // Object dest, int destPos,
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4678 // int length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4679 bool LibraryCallKit::inline_arraycopy() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4680 // Get the arguments.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4681 Node* src = argument(0); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4682 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
4683 Node* dest = argument(2); // type: oop
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4684 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
4685 Node* length = argument(4); // type: int
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4686
a61af66fc99e Initial load
duke
parents:
diff changeset
4687 // Compile time checks. If any of these checks cannot be verified at compile time,
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 // 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
4689 // is. The checks we choose to mandate at compile time are:
a61af66fc99e Initial load
duke
parents:
diff changeset
4690 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4691 // (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
4692 const Type* src_type = src->Value(&_gvn);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 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
4694 const TypeAryPtr* top_src = src_type->isa_aryptr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 const TypeAryPtr* top_dest = dest_type->isa_aryptr();
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4696
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4697 // Do we have the type of src?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4698 bool has_src = (top_src != NULL && top_src->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4699 // Do we have the type of dest?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4700 bool has_dest = (top_dest != NULL && top_dest->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4701 // Is the type for src from speculation?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4702 bool src_spec = false;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4703 // Is the type for dest from speculation?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4704 bool dest_spec = false;
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 if (!has_src || !has_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4707 // 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
4708 // 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
4709 // and dest so that it pays off.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4710
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4711 // 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
4712 bool could_have_src = has_src;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4713 // 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
4714 bool could_have_dest = has_dest;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4715
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4716 ciKlass* src_k = NULL;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4717 if (!has_src) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4718 src_k = src_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4719 if (src_k != NULL && src_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4720 could_have_src = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4721 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4722 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4723
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4724 ciKlass* dest_k = NULL;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4725 if (!has_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4726 dest_k = dest_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4727 if (dest_k != NULL && dest_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4728 could_have_dest = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4729 }
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 if (could_have_src && could_have_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4733 // 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
4734 if (!has_src) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4735 src = maybe_cast_profiled_obj(src, src_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4736 src_type = _gvn.type(src);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4737 top_src = src_type->isa_aryptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4738 has_src = (top_src != NULL && top_src->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4739 src_spec = true;
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 (!has_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4742 dest = maybe_cast_profiled_obj(dest, dest_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4743 dest_type = _gvn.type(dest);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4744 top_dest = dest_type->isa_aryptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4745 has_dest = (top_dest != NULL && top_dest->klass() != NULL);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4746 dest_spec = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4747 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4748 }
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
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4751 if (!has_src || !has_dest) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4752 // Conservatively insert a memory barrier on all memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
4753 // Do not let writes into the source float below the arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4754 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4755
a61af66fc99e Initial load
duke
parents:
diff changeset
4756 // Call StubRoutines::generic_arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
4757 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
4758 src, src_offset, dest, dest_offset, length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4759
a61af66fc99e Initial load
duke
parents:
diff changeset
4760 // Do not let reads from the destination float above the arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4761 // Since we cannot type the arrays, we don't know which slices
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 // might be affected. We could restrict this barrier only to those
a61af66fc99e Initial load
duke
parents:
diff changeset
4763 // memory slices which pertain to array elements--but don't bother.
a61af66fc99e Initial load
duke
parents:
diff changeset
4764 if (!InsertMemBarAfterArraycopy)
a61af66fc99e Initial load
duke
parents:
diff changeset
4765 // (If InsertMemBarAfterArraycopy, there is already one in place.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4766 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
4767 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4769
a61af66fc99e Initial load
duke
parents:
diff changeset
4770 // (2) src and dest arrays must have elements of the same BasicType
a61af66fc99e Initial load
duke
parents:
diff changeset
4771 // Figure out the size and type of the elements we will be copying.
a61af66fc99e Initial load
duke
parents:
diff changeset
4772 BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
4773 BasicType dest_elem = top_dest->klass()->as_array_klass()->element_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 if (src_elem == T_ARRAY) src_elem = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
4776
a61af66fc99e Initial load
duke
parents:
diff changeset
4777 if (src_elem != dest_elem || dest_elem == T_VOID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4778 // The component types are not the same or are not recognized. Punt.
a61af66fc99e Initial load
duke
parents:
diff changeset
4779 // (But, avoid the native method wrapper to JVM_ArrayCopy.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4780 generate_slow_arraycopy(TypePtr::BOTTOM,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4781 src, src_offset, dest, dest_offset, length,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4782 /*dest_uninitialized*/false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4785
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4786 if (src_elem == T_OBJECT) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4787 // 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
4788 // 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
4789 // 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
4790 // routine (without a subtype check on every element)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4791 // Do we have the exact type of src?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4792 bool could_have_src = src_spec;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4793 // Do we have the exact type of dest?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4794 bool could_have_dest = dest_spec;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4795 ciKlass* src_k = top_src->klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4796 ciKlass* dest_k = top_dest->klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4797 if (!src_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4798 src_k = src_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4799 if (src_k != NULL && src_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4800 could_have_src = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4801 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4802 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4803 if (!dest_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4804 dest_k = dest_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4805 if (dest_k != NULL && dest_k->is_array_klass()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4806 could_have_dest = true;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4807 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4808 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4809 if (could_have_src && could_have_dest) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4810 // 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
4811 if (could_have_src && !src_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4812 src = maybe_cast_profiled_obj(src, src_k);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4813 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4814 if (could_have_dest && !dest_spec) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4815 dest = maybe_cast_profiled_obj(dest, dest_k);
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 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
4819
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4820 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4821 // We will make a fast path for this call to arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4822
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 // We have the following tests left to perform:
a61af66fc99e Initial load
duke
parents:
diff changeset
4824 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4825 // (3) src and dest must not be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
4826 // (4) src_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4827 // (5) dest_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4828 // (6) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4829 // (7) src_offset + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 // (8) dest_offset + length must not exceed length of dest.
a61af66fc99e Initial load
duke
parents:
diff changeset
4831 // (9) each element of an oop array must be assignable
a61af66fc99e Initial load
duke
parents:
diff changeset
4832
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4833 RegionNode* slow_region = new (C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4835
a61af66fc99e Initial load
duke
parents:
diff changeset
4836 // (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
4837 // We currently perform our null checks with the null_check routine.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4838 // This means that the null exceptions will be reported in the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 // rather than (correctly) reported inside of the native arraycopy call.
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 // This should be corrected, given time. We do our null check with the
a61af66fc99e Initial load
duke
parents:
diff changeset
4841 // stack pointer restored.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4842 src = null_check(src, T_ARRAY);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
4843 dest = null_check(dest, T_ARRAY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4844
a61af66fc99e Initial load
duke
parents:
diff changeset
4845 // (4) src_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4846 generate_negative_guard(src_offset, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4847
a61af66fc99e Initial load
duke
parents:
diff changeset
4848 // (5) dest_offset must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
4849 generate_negative_guard(dest_offset, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4850
a61af66fc99e Initial load
duke
parents:
diff changeset
4851 // (6) length must not be negative (moved to generate_arraycopy()).
a61af66fc99e Initial load
duke
parents:
diff changeset
4852 // generate_negative_guard(length, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4853
a61af66fc99e Initial load
duke
parents:
diff changeset
4854 // (7) src_offset + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
4855 generate_limit_guard(src_offset, length,
a61af66fc99e Initial load
duke
parents:
diff changeset
4856 load_array_length(src),
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4858
a61af66fc99e Initial load
duke
parents:
diff changeset
4859 // (8) dest_offset + length must not exceed length of dest.
a61af66fc99e Initial load
duke
parents:
diff changeset
4860 generate_limit_guard(dest_offset, length,
a61af66fc99e Initial load
duke
parents:
diff changeset
4861 load_array_length(dest),
a61af66fc99e Initial load
duke
parents:
diff changeset
4862 slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4863
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 // (9) each element of an oop array must be assignable
a61af66fc99e Initial load
duke
parents:
diff changeset
4865 // The generate_arraycopy subroutine checks this.
a61af66fc99e Initial load
duke
parents:
diff changeset
4866
a61af66fc99e Initial load
duke
parents:
diff changeset
4867 // This is where the memory effects are placed:
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 const TypePtr* adr_type = TypeAryPtr::get_array_body_type(dest_elem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4869 generate_arraycopy(adr_type, dest_elem,
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 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
4871 false, false, slow_region);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4872
a61af66fc99e Initial load
duke
parents:
diff changeset
4873 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4875
a61af66fc99e Initial load
duke
parents:
diff changeset
4876 //-----------------------------generate_arraycopy----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4877 // Generate an optimized call to arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
4878 // Caller must guard against non-arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 // Caller must determine a common array basic-type for both arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
4880 // Caller must validate offsets against array bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
4881 // The slow_region has already collected guard failure paths
a61af66fc99e Initial load
duke
parents:
diff changeset
4882 // (such as out of bounds length or non-conformable array types).
a61af66fc99e Initial load
duke
parents:
diff changeset
4883 // The generated code has this shape, in general:
a61af66fc99e Initial load
duke
parents:
diff changeset
4884 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4885 // if (length == 0) return // via zero_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 // slowval = -1
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 // if (types unknown) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4888 // slowval = call generic copy loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4889 // if (slowval == 0) return // via checked_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4890 // } else if (indexes in bounds) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4891 // if ((is object array) && !(array type check)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 // slowval = call checked copy loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 // if (slowval == 0) return // via checked_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4894 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 // call bulk copy loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4896 // return // via fast_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4897 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
4898 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
4899 // // adjust params for remaining work:
a61af66fc99e Initial load
duke
parents:
diff changeset
4900 // if (slowval != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4901 // n = -1^slowval; src_offset += n; dest_offset += n; length -= n
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
4903 // slow_region:
a61af66fc99e Initial load
duke
parents:
diff changeset
4904 // call slow arraycopy(src, src_offset, dest, dest_offset, length)
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 // return // via slow_call_path
a61af66fc99e Initial load
duke
parents:
diff changeset
4906 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4907 // This routine is used from several intrinsics: System.arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
4908 // Object.clone (the array subcase), and Arrays.copyOf[Range].
a61af66fc99e Initial load
duke
parents:
diff changeset
4909 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4910 void
a61af66fc99e Initial load
duke
parents:
diff changeset
4911 LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
4912 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
4913 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4914 Node* dest, Node* dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 Node* copy_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
4916 bool disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 bool length_never_negative,
a61af66fc99e Initial load
duke
parents:
diff changeset
4918 RegionNode* slow_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4919
a61af66fc99e Initial load
duke
parents:
diff changeset
4920 if (slow_region == NULL) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4921 slow_region = new(C) RegionNode(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4922 record_for_igvn(slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4924
a61af66fc99e Initial load
duke
parents:
diff changeset
4925 Node* original_dest = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 AllocateArrayNode* alloc = NULL; // used for zeroing, if needed
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4927 bool dest_uninitialized = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4928
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 // See if this is the initialization of a newly-allocated array.
a61af66fc99e Initial load
duke
parents:
diff changeset
4930 // If so, we will take responsibility here for initializing it to zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
4931 // (Note: Because tightly_coupled_allocation performs checks on the
a61af66fc99e Initial load
duke
parents:
diff changeset
4932 // out-edges of the dest, we need to avoid making derived pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
4933 // from it until we have checked its uses.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4934 if (ReduceBulkZeroing
a61af66fc99e Initial load
duke
parents:
diff changeset
4935 && !ZeroTLAB // pointless if already zeroed
a61af66fc99e Initial load
duke
parents:
diff changeset
4936 && basic_elem_type != T_CONFLICT // avoid corner case
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
4937 && !src->eqv_uncast(dest)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4938 && ((alloc = tightly_coupled_allocation(dest, slow_region))
a61af66fc99e Initial load
duke
parents:
diff changeset
4939 != NULL)
34
545c277a3ecf 6667581: Don't generate initialization (by 0) code for arrays with size 0
kvn
parents: 29
diff changeset
4940 && _gvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 && alloc->maybe_set_complete(&_gvn)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 // "You break it, you buy it."
a61af66fc99e Initial load
duke
parents:
diff changeset
4943 InitializeNode* init = alloc->initialization();
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 assert(init->is_complete(), "we just did this");
3961
a92cdbac8b9e 7081933: Use zeroing elimination optimization for large array
kvn
parents: 3742
diff changeset
4945 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
4946 assert(dest->is_CheckCastPP(), "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 assert(dest->in(0)->in(0) == init, "dest pinned");
a61af66fc99e Initial load
duke
parents:
diff changeset
4948 adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 // From this point on, every exit path is responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
4950 // initializing any non-copied parts of the object to zero.
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4951 // 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
4952 // with G1, eliding pre-barriers. See CR 6627983.
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4953 dest_uninitialized = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4955 // No zeroing elimination here.
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 alloc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 //original_dest = dest;
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4958 //dest_uninitialized = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4960
a61af66fc99e Initial load
duke
parents:
diff changeset
4961 // Results are placed here:
a61af66fc99e Initial load
duke
parents:
diff changeset
4962 enum { fast_path = 1, // normal void-returning assembly stub
a61af66fc99e Initial load
duke
parents:
diff changeset
4963 checked_path = 2, // special assembly stub with cleanup
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 slow_call_path = 3, // something went wrong; call the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
4965 zero_path = 4, // bypass when length of copy is zero
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 bcopy_path = 5, // copy primitive array by 64-bit blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
4967 PATH_LIMIT = 6
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
4969 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
4970 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
4971 PhiNode* result_memory = new(C) PhiNode(result_region, Type::MEMORY, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 record_for_igvn(result_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 _gvn.set_type_bottom(result_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
4974 _gvn.set_type_bottom(result_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
4975 assert(adr_type != TypePtr::BOTTOM, "must be RawMem or a T[] slice");
a61af66fc99e Initial load
duke
parents:
diff changeset
4976
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 // The slow_control path:
a61af66fc99e Initial load
duke
parents:
diff changeset
4978 Node* slow_control;
a61af66fc99e Initial load
duke
parents:
diff changeset
4979 Node* slow_i_o = i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
4980 Node* slow_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 debug_only(slow_control = (Node*) badAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
4982
a61af66fc99e Initial load
duke
parents:
diff changeset
4983 // Checked control path:
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 Node* checked_control = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
4985 Node* checked_mem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4986 Node* checked_i_o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4987 Node* checked_value = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4988
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 if (basic_elem_type == T_CONFLICT) {
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4990 assert(!dest_uninitialized, "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4991 Node* cv = generate_generic_arraycopy(adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
4992 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
4993 copy_length, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4994 if (cv == NULL) cv = intcon(-1); // failure (no stub available)
a61af66fc99e Initial load
duke
parents:
diff changeset
4995 checked_control = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 checked_i_o = i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
4997 checked_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
4998 checked_value = cv;
a61af66fc99e Initial load
duke
parents:
diff changeset
4999 set_control(top()); // no fast path
a61af66fc99e Initial load
duke
parents:
diff changeset
5000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5001
a61af66fc99e Initial load
duke
parents:
diff changeset
5002 Node* not_pos = generate_nonpositive_guard(copy_length, length_never_negative);
a61af66fc99e Initial load
duke
parents:
diff changeset
5003 if (not_pos != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5004 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5005 set_control(not_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
5006
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 // (6) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 if (!length_never_negative) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 generate_negative_guard(copy_length, slow_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
5010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5011
836
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5012 // copy_length is 0.
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5013 if (!stopped() && dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 Node* dest_length = alloc->in(AllocateNode::ALength);
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
5015 if (copy_length->eqv_uncast(dest_length)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 || _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
5017 // There is no zeroing to do. No need for a secondary raw memory barrier.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5018 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 // Clear the whole thing since there are no source elements to copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
5020 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5021 intcon(0), NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5022 alloc->in(AllocateNode::AllocSize));
836
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5023 // 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
5024 // 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
5025 // 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
5026 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
5027 Compile::AliasIdxRaw,
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5028 top())->as_Initialize();
4325cdaa78ad 6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents: 833
diff changeset
5029 init->set_complete(&_gvn); // (there is no corresponding AllocateNode)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5032
a61af66fc99e Initial load
duke
parents:
diff changeset
5033 // Present the results of the fast call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5034 result_region->init_req(zero_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5035 result_i_o ->init_req(zero_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 result_memory->init_req(zero_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5038
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5039 if (!stopped() && dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5040 // We have to initialize the *uncopied* part of the array to zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
5041 // The copy destination is the slice dest[off..off+len]. The other slices
a61af66fc99e Initial load
duke
parents:
diff changeset
5042 // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length].
a61af66fc99e Initial load
duke
parents:
diff changeset
5043 Node* dest_size = alloc->in(AllocateNode::AllocSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 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
5045 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
5046 copy_length));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5047
a61af66fc99e Initial load
duke
parents:
diff changeset
5048 // If there is a head section that needs zeroing, do it now.
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 if (find_int_con(dest_offset, -1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5050 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5051 intcon(0), dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5054
a61af66fc99e Initial load
duke
parents:
diff changeset
5055 // Next, perform a dynamic check on the tail length.
a61af66fc99e Initial load
duke
parents:
diff changeset
5056 // It is often zero, and we can win big if we prove this.
a61af66fc99e Initial load
duke
parents:
diff changeset
5057 // There are two wins: Avoid generating the ClearArray
a61af66fc99e Initial load
duke
parents:
diff changeset
5058 // with its attendant messy index arithmetic, and upgrade
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 // the copy to a more hardware-friendly word size of 64 bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 Node* tail_ctl = NULL;
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4771
diff changeset
5061 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
5062 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
5063 Node* bol_lt = _gvn.transform(new(C) BoolNode(cmp_lt, BoolTest::lt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5064 tail_ctl = generate_slow_guard(bol_lt, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5065 assert(tail_ctl != NULL || !stopped(), "must be an outcome");
a61af66fc99e Initial load
duke
parents:
diff changeset
5066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5067
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 // At this point, let's assume there is no tail.
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 if (!stopped() && alloc != NULL && basic_elem_type != T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5070 // There is no tail. Try an upgrade to a 64-bit copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
5071 bool didit = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5072 { PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5073 didit = generate_block_arraycopy(adr_type, basic_elem_type, alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
5074 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5075 dest_size, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5076 if (didit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 // Present the results of the block-copying fast call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5078 result_region->init_req(bcopy_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5079 result_i_o ->init_req(bcopy_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5080 result_memory->init_req(bcopy_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5083 if (didit)
a61af66fc99e Initial load
duke
parents:
diff changeset
5084 set_control(top()); // no regular fast path
a61af66fc99e Initial load
duke
parents:
diff changeset
5085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5086
a61af66fc99e Initial load
duke
parents:
diff changeset
5087 // Clear the tail, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 if (tail_ctl != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5089 Node* notail_ctl = stopped() ? NULL : control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 set_control(tail_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 if (notail_ctl == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5092 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5093 dest_tail, NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 dest_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
5095 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 // Make a local merge.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5097 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
5098 Node* done_mem = new(C) PhiNode(done_ctl, Type::MEMORY, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5099 done_ctl->init_req(1, notail_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5100 done_mem->init_req(1, memory(adr_type));
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 done_ctl->init_req(2, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 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
5106 set_control( _gvn.transform(done_ctl));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5107 set_memory( _gvn.transform(done_mem), adr_type );
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5111
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 BasicType copy_type = basic_elem_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 assert(basic_elem_type != T_ARRAY, "caller must fix this");
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 if (!stopped() && copy_type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5115 // If src and dest have compatible element types, we can copy bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 // Types S[] and D[] are compatible if D is a supertype of S.
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 // If they are not, we will use checked_oop_disjoint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 // which performs a fast optimistic per-oop check, and backs off
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 // further to JVM_ArrayCopy on the first per-oop check that fails.
a61af66fc99e Initial load
duke
parents:
diff changeset
5121 // (Actually, we don't move raw bits only; the GC requires card marks.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5122
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6615
diff changeset
5123 // Get the Klass* for both src and dest
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5124 Node* src_klass = load_object_klass(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 Node* dest_klass = load_object_klass(dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
5126
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 // Generate the subtype check.
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 // This might fold up statically, or then again it might not.
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 // Non-static example: Copying List<String>.elements to a new String[].
a61af66fc99e Initial load
duke
parents:
diff changeset
5131 // The backing store for a List<String> is always an Object[],
a61af66fc99e Initial load
duke
parents:
diff changeset
5132 // but its elements are always type String, if the generic types
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 // are correct at the source level.
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5135 // Test S[] against D[], not S against D, because (probably)
a61af66fc99e Initial load
duke
parents:
diff changeset
5136 // the secondary supertype cache is less busy for S[] than S.
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 // This usually only matters when D is an interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 Node* not_subtype_ctrl = gen_subtype_check(src_klass, dest_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 // Plug failing path into checked_oop_disjoint_arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
5140 if (not_subtype_ctrl != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5141 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 set_control(not_subtype_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 // (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
5144 int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5145 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
5146 Node* n1 = LoadKlassNode::make(_gvn, immutable_memory(), p1, TypeRawPtr::BOTTOM);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 Node* dest_elem_klass = _gvn.transform(n1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 Node* cv = generate_checkcast_arraycopy(adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 dest_elem_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5151 ConvI2X(copy_length), dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5152 if (cv == NULL) cv = intcon(-1); // failure (no stub available)
a61af66fc99e Initial load
duke
parents:
diff changeset
5153 checked_control = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5154 checked_i_o = i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
5155 checked_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5156 checked_value = cv;
a61af66fc99e Initial load
duke
parents:
diff changeset
5157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5158 // At this point we know we do not need type checks on oop stores.
a61af66fc99e Initial load
duke
parents:
diff changeset
5159
a61af66fc99e Initial load
duke
parents:
diff changeset
5160 // Let's see if we need card marks:
a61af66fc99e Initial load
duke
parents:
diff changeset
5161 if (alloc != NULL && use_ReduceInitialCardMarks()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5162 // 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
5163 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
5164 assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5165 "sizes agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
5166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5168
a61af66fc99e Initial load
duke
parents:
diff changeset
5169 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 // Generate the fast path, if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
5171 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5172 generate_unchecked_arraycopy(adr_type, copy_type, disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
5173 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5174 ConvI2X(copy_length), dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5175
a61af66fc99e Initial load
duke
parents:
diff changeset
5176 // Present the results of the fast call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5177 result_region->init_req(fast_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5178 result_i_o ->init_req(fast_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 result_memory->init_req(fast_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5181
a61af66fc99e Initial load
duke
parents:
diff changeset
5182 // Here are all the slow paths up to this point, in one bundle:
a61af66fc99e Initial load
duke
parents:
diff changeset
5183 slow_control = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5184 if (slow_region != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5185 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
5186 DEBUG_ONLY(slow_region = (RegionNode*)badAddress);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5187
a61af66fc99e Initial load
duke
parents:
diff changeset
5188 set_control(checked_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
5189 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5190 // Clean up after the checked call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5191 // The returned value is either 0 or -1^K,
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 // 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
5193 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
5194 Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5195 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
5196
a61af66fc99e Initial load
duke
parents:
diff changeset
5197 // 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
5198 Node* checks_done = _gvn.transform(new(C) IfTrueNode(iff));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5199 result_region->init_req(checked_path, checks_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 result_i_o ->init_req(checked_path, checked_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 result_memory->init_req(checked_path, checked_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5202
a61af66fc99e Initial load
duke
parents:
diff changeset
5203 // 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
5204 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
5205 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
5206 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
5207 PhiNode* slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 record_for_igvn(slow_reg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 slow_reg2 ->init_req(1, slow_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
5210 slow_i_o2 ->init_req(1, slow_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
5211 slow_mem2 ->init_req(1, slow_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5212 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
5213 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
5214 slow_mem2 ->init_req(2, checked_mem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5215
a61af66fc99e Initial load
duke
parents:
diff changeset
5216 slow_control = _gvn.transform(slow_reg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 slow_i_o = _gvn.transform(slow_i_o2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5218 slow_mem = _gvn.transform(slow_mem2);
a61af66fc99e Initial load
duke
parents:
diff changeset
5219
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 if (alloc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5221 // We'll restart from the very beginning, after zeroing the whole thing.
a61af66fc99e Initial load
duke
parents:
diff changeset
5222 // This can cause double writes, but that's OK since dest is brand new.
a61af66fc99e Initial load
duke
parents:
diff changeset
5223 // So we ignore the low 31 bits of the value returned from the stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
5224 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5225 // We must continue the copy exactly where it failed, or else
a61af66fc99e Initial load
duke
parents:
diff changeset
5226 // 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
5227 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
5228 Node* slow_offset = new(C) PhiNode(slow_reg2, TypeInt::INT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5229 slow_offset->init_req(1, intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
5230 slow_offset->init_req(2, checked_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5231 slow_offset = _gvn.transform(slow_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5232
a61af66fc99e Initial load
duke
parents:
diff changeset
5233 // 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
5234 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
5235 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
5236 Node* length_minus = _gvn.transform(new(C) SubINode(copy_length, slow_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5237
a61af66fc99e Initial load
duke
parents:
diff changeset
5238 // Tweak the node variables to adjust the code produced below:
a61af66fc99e Initial load
duke
parents:
diff changeset
5239 src_offset = src_off_plus;
a61af66fc99e Initial load
duke
parents:
diff changeset
5240 dest_offset = dest_off_plus;
a61af66fc99e Initial load
duke
parents:
diff changeset
5241 copy_length = length_minus;
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5244
a61af66fc99e Initial load
duke
parents:
diff changeset
5245 set_control(slow_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
5246 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5247 // Generate the slow path, if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 PreserveJVMState pjvms(this); // replace_in_map may trash the map
a61af66fc99e Initial load
duke
parents:
diff changeset
5249
a61af66fc99e Initial load
duke
parents:
diff changeset
5250 set_memory(slow_mem, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5251 set_i_o(slow_i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
5252
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5253 if (dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5254 generate_clear_array(adr_type, dest, basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5255 intcon(0), NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
5256 alloc->in(AllocateNode::AllocSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
5257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5258
a61af66fc99e Initial load
duke
parents:
diff changeset
5259 generate_slow_arraycopy(adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5260 src, src_offset, dest, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5261 copy_length, /*dest_uninitialized*/false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5262
a61af66fc99e Initial load
duke
parents:
diff changeset
5263 result_region->init_req(slow_call_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
5264 result_i_o ->init_req(slow_call_path, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
5265 result_memory->init_req(slow_call_path, memory(adr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
5266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5267
a61af66fc99e Initial load
duke
parents:
diff changeset
5268 // Remove unused edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
5269 for (uint i = 1; i < result_region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5270 if (result_region->in(i) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5271 result_region->init_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
5272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5273
a61af66fc99e Initial load
duke
parents:
diff changeset
5274 // Finished; return the combined state.
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5275 set_control( _gvn.transform(result_region));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5276 set_i_o( _gvn.transform(result_i_o) );
a61af66fc99e Initial load
duke
parents:
diff changeset
5277 set_memory( _gvn.transform(result_memory), adr_type );
a61af66fc99e Initial load
duke
parents:
diff changeset
5278
a61af66fc99e Initial load
duke
parents:
diff changeset
5279 // The memory edges above are precise in order to model effects around
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
5280 // array copies accurately to allow value numbering of field loads around
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5281 // arraycopy. Such field loads, both before and after, are common in Java
a61af66fc99e Initial load
duke
parents:
diff changeset
5282 // collections and similar classes involving header/array data structures.
a61af66fc99e Initial load
duke
parents:
diff changeset
5283 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5284 // But with low number of register or when some registers are used or killed
a61af66fc99e Initial load
duke
parents:
diff changeset
5285 // by arraycopy calls it causes registers spilling on stack. See 6544710.
a61af66fc99e Initial load
duke
parents:
diff changeset
5286 // The next memory barrier is added to avoid it. If the arraycopy can be
a61af66fc99e Initial load
duke
parents:
diff changeset
5287 // optimized away (which it can, sometimes) then we can manually remove
a61af66fc99e Initial load
duke
parents:
diff changeset
5288 // the membar also.
958
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
5289 //
c7e94e8fff43 6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents: 950
diff changeset
5290 // 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
5291 if (alloc != NULL) {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5292 // 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
5293 // 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
5294 // other threads.
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5295 // 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
5296 // 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
5297 // AllocateNode and eliminate the MemBarStoreStoreNode if possible
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
5298 // 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
5299 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
5300 } else if (InsertMemBarAfterArraycopy)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5301 insert_mem_bar(Op_MemBarCPUOrder);
a61af66fc99e Initial load
duke
parents:
diff changeset
5302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5303
a61af66fc99e Initial load
duke
parents:
diff changeset
5304
a61af66fc99e Initial load
duke
parents:
diff changeset
5305 // Helper function which determines if an arraycopy immediately follows
a61af66fc99e Initial load
duke
parents:
diff changeset
5306 // an allocation, with no intervening tests or other escapes for the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5307 AllocateArrayNode*
a61af66fc99e Initial load
duke
parents:
diff changeset
5308 LibraryCallKit::tightly_coupled_allocation(Node* ptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
5309 RegionNode* slow_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5310 if (stopped()) return NULL; // no fast path
a61af66fc99e Initial load
duke
parents:
diff changeset
5311 if (C->AliasLevel() == 0) return NULL; // no MergeMems around
a61af66fc99e Initial load
duke
parents:
diff changeset
5312
a61af66fc99e Initial load
duke
parents:
diff changeset
5313 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(ptr, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5314 if (alloc == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5315
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 Node* rawmem = memory(Compile::AliasIdxRaw);
a61af66fc99e Initial load
duke
parents:
diff changeset
5317 // Is the allocation's memory state untouched?
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 if (!(rawmem->is_Proj() && rawmem->in(0)->is_Initialize())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 // Bail out if there have been raw-memory effects since the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5320 // (Example: There might have been a call or safepoint.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5321 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5323 rawmem = rawmem->in(0)->as_Initialize()->memory(Compile::AliasIdxRaw);
a61af66fc99e Initial load
duke
parents:
diff changeset
5324 if (!(rawmem->is_Proj() && rawmem->in(0) == alloc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5325 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5327
a61af66fc99e Initial load
duke
parents:
diff changeset
5328 // There must be no unexpected observers of this allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 for (DUIterator_Fast imax, i = ptr->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5330 Node* obs = ptr->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5331 if (obs != this->map()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5332 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5335
a61af66fc99e Initial load
duke
parents:
diff changeset
5336 // This arraycopy must unconditionally follow the allocation of the ptr.
a61af66fc99e Initial load
duke
parents:
diff changeset
5337 Node* alloc_ctl = ptr->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5338 assert(just_allocated_object(alloc_ctl) == ptr, "most recent allo");
a61af66fc99e Initial load
duke
parents:
diff changeset
5339
a61af66fc99e Initial load
duke
parents:
diff changeset
5340 Node* ctl = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
5341 while (ctl != alloc_ctl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5342 // There may be guards which feed into the slow_region.
a61af66fc99e Initial load
duke
parents:
diff changeset
5343 // Any other control flow means that we might not get a chance
a61af66fc99e Initial load
duke
parents:
diff changeset
5344 // to finish initializing the allocated object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5345 if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5346 IfNode* iff = ctl->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
5347 Node* not_ctl = iff->proj_out(1 - ctl->as_Proj()->_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
5348 assert(not_ctl != NULL && not_ctl != ctl, "found alternate");
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5350 ctl = iff->in(0); // This test feeds the known slow_region.
a61af66fc99e Initial load
duke
parents:
diff changeset
5351 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 // One more try: Various low-level checks bottom out in
a61af66fc99e Initial load
duke
parents:
diff changeset
5354 // uncommon traps. If the debug-info of the trap omits
a61af66fc99e Initial load
duke
parents:
diff changeset
5355 // any reference to the allocation, as we've already
a61af66fc99e Initial load
duke
parents:
diff changeset
5356 // observed, then there can be no objection to the trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5357 bool found_trap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5358 for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5359 Node* obs = not_ctl->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
5360 if (obs->in(0) == not_ctl && obs->is_Call() &&
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1746
diff changeset
5361 (obs->as_Call()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5362 found_trap = true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
5363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5365 if (found_trap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5366 ctl = iff->in(0); // This test feeds a harmless uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5367 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5370 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5372
a61af66fc99e Initial load
duke
parents:
diff changeset
5373 // If we get this far, we have an allocation which immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
5374 // precedes the arraycopy, and we can take over zeroing the new object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5375 // The arraycopy will finish the initialization, and provide
a61af66fc99e Initial load
duke
parents:
diff changeset
5376 // a new control state to which we will anchor the destination pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
5377
a61af66fc99e Initial load
duke
parents:
diff changeset
5378 return alloc;
a61af66fc99e Initial load
duke
parents:
diff changeset
5379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5380
a61af66fc99e Initial load
duke
parents:
diff changeset
5381 // Helper for initialization of arrays, creating a ClearArray.
a61af66fc99e Initial load
duke
parents:
diff changeset
5382 // It writes zero bits in [start..end), within the body of an array object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5383 // The memory effects are all chained onto the 'adr_type' alias category.
a61af66fc99e Initial load
duke
parents:
diff changeset
5384 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5385 // Since the object is otherwise uninitialized, we are free
a61af66fc99e Initial load
duke
parents:
diff changeset
5386 // to put a little "slop" around the edges of the cleared area,
a61af66fc99e Initial load
duke
parents:
diff changeset
5387 // as long as it does not go back into the array's header,
a61af66fc99e Initial load
duke
parents:
diff changeset
5388 // or beyond the array end within the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5389 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5390 // The lower edge can be rounded down to the nearest jint and the
a61af66fc99e Initial load
duke
parents:
diff changeset
5391 // upper edge can be rounded up to the nearest MinObjAlignmentInBytes.
a61af66fc99e Initial load
duke
parents:
diff changeset
5392 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5393 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
5394 // adr_type memory slice where writes are generated
a61af66fc99e Initial load
duke
parents:
diff changeset
5395 // dest oop of the destination array
a61af66fc99e Initial load
duke
parents:
diff changeset
5396 // basic_elem_type element type of the destination
a61af66fc99e Initial load
duke
parents:
diff changeset
5397 // slice_idx array index of first element to store
a61af66fc99e Initial load
duke
parents:
diff changeset
5398 // slice_len number of elements to store (or NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5399 // dest_size total size in bytes of the array object
a61af66fc99e Initial load
duke
parents:
diff changeset
5400 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5401 // Exactly one of slice_len or dest_size must be non-NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
5402 // If dest_size is non-NULL, zeroing extends to the end of the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
5403 // If slice_len is non-NULL, the slice_idx value must be a constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
5404 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5405 LibraryCallKit::generate_clear_array(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5406 Node* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5407 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5408 Node* slice_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
5409 Node* slice_len,
a61af66fc99e Initial load
duke
parents:
diff changeset
5410 Node* dest_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5411 // one or the other but not both of slice_len and dest_size:
a61af66fc99e Initial load
duke
parents:
diff changeset
5412 assert((slice_len != NULL? 1: 0) + (dest_size != NULL? 1: 0) == 1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5413 if (slice_len == NULL) slice_len = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5414 if (dest_size == NULL) dest_size = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5415
a61af66fc99e Initial load
duke
parents:
diff changeset
5416 // operate on this memory slice:
a61af66fc99e Initial load
duke
parents:
diff changeset
5417 Node* mem = memory(adr_type); // memory slice to operate on
a61af66fc99e Initial load
duke
parents:
diff changeset
5418
a61af66fc99e Initial load
duke
parents:
diff changeset
5419 // scaling and rounding of indexes:
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
5420 int scale = exact_log2(type2aelembytes(basic_elem_type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5421 int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5422 int clear_low = (-1 << scale) & (BytesPerInt - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5423 int bump_bit = (-1 << scale) & BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
5424
a61af66fc99e Initial load
duke
parents:
diff changeset
5425 // determine constant starts and ends
a61af66fc99e Initial load
duke
parents:
diff changeset
5426 const intptr_t BIG_NEG = -128;
a61af66fc99e Initial load
duke
parents:
diff changeset
5427 assert(BIG_NEG + 2*abase < 0, "neg enough");
a61af66fc99e Initial load
duke
parents:
diff changeset
5428 intptr_t slice_idx_con = (intptr_t) find_int_con(slice_idx, BIG_NEG);
a61af66fc99e Initial load
duke
parents:
diff changeset
5429 intptr_t slice_len_con = (intptr_t) find_int_con(slice_len, BIG_NEG);
a61af66fc99e Initial load
duke
parents:
diff changeset
5430 if (slice_len_con == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5431 return; // nothing to do here
a61af66fc99e Initial load
duke
parents:
diff changeset
5432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5433 intptr_t start_con = (abase + (slice_idx_con << scale)) & ~clear_low;
a61af66fc99e Initial load
duke
parents:
diff changeset
5434 intptr_t end_con = find_intptr_t_con(dest_size, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5435 if (slice_idx_con >= 0 && slice_len_con >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5436 assert(end_con < 0, "not two cons");
a61af66fc99e Initial load
duke
parents:
diff changeset
5437 end_con = round_to(abase + ((slice_idx_con + slice_len_con) << scale),
a61af66fc99e Initial load
duke
parents:
diff changeset
5438 BytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
5439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5440
a61af66fc99e Initial load
duke
parents:
diff changeset
5441 if (start_con >= 0 && end_con >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5442 // Constant start and end. Simple.
a61af66fc99e Initial load
duke
parents:
diff changeset
5443 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5444 start_con, end_con, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5445 } else if (start_con >= 0 && dest_size != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5446 // Constant start, pre-rounded end after the tail of the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
5447 Node* end = dest_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
5448 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5449 start_con, end, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5450 } else if (start_con >= 0 && slice_len != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5451 // Constant start, non-constant end. End needs rounding up.
a61af66fc99e Initial load
duke
parents:
diff changeset
5452 // End offset = round_up(abase + ((slice_idx_con + slice_len) << scale), 8)
a61af66fc99e Initial load
duke
parents:
diff changeset
5453 intptr_t end_base = abase + (slice_idx_con << scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
5454 int end_round = (-1 << scale) & (BytesPerLong - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5455 Node* end = ConvI2X(slice_len);
a61af66fc99e Initial load
duke
parents:
diff changeset
5456 if (scale != 0)
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5457 end = _gvn.transform(new(C) LShiftXNode(end, intcon(scale) ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5458 end_base += end_round;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5459 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
5460 end = _gvn.transform(new(C) AndXNode(end, MakeConX(~end_round)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5461 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5462 start_con, end, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5463 } else if (start_con < 0 && dest_size != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5464 // Non-constant start, pre-rounded end after the tail of the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
5465 // This is almost certainly a "round-to-end" operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5466 Node* start = slice_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
5467 start = ConvI2X(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
5468 if (scale != 0)
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5469 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
5470 start = _gvn.transform(new(C) AddXNode(start, MakeConX(abase)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5471 if ((bump_bit | clear_low) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5472 int to_clear = (bump_bit | clear_low);
a61af66fc99e Initial load
duke
parents:
diff changeset
5473 // Align up mod 8, then store a jint zero unconditionally
a61af66fc99e Initial load
duke
parents:
diff changeset
5474 // 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
5475 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
5476 < 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
5477 bump_bit = 0;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5478 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
5479 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5480 // 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
5481 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
5482 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
5483 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5484 // 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
5485 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
5486 if (bump_bit != 0) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5487 // 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
5488 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
5489 Node* p1 = basic_plus_adr(dest, x1);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5490 mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 34
diff changeset
5491 mem = _gvn.transform(mem);
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 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5494 Node* end = dest_size; // pre-rounded
a61af66fc99e Initial load
duke
parents:
diff changeset
5495 mem = ClearArrayNode::clear_memory(control(), mem, dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
5496 start, end, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
5497 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5498 // Non-constant start, unrounded non-constant end.
a61af66fc99e Initial load
duke
parents:
diff changeset
5499 // (Nobody zeroes a random midsection of an array using this routine.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5500 ShouldNotReachHere(); // fix caller
a61af66fc99e Initial load
duke
parents:
diff changeset
5501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5502
a61af66fc99e Initial load
duke
parents:
diff changeset
5503 // Done.
a61af66fc99e Initial load
duke
parents:
diff changeset
5504 set_memory(mem, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5506
a61af66fc99e Initial load
duke
parents:
diff changeset
5507
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5510 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5511 AllocateNode* alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
5512 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5513 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5514 Node* dest_size, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5515 // 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
5516 int scale = exact_log2(type2aelembytes(basic_elem_type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5517 if (scale >= LogBytesPerLong)
a61af66fc99e Initial load
duke
parents:
diff changeset
5518 return false; // it is already a block transfer
a61af66fc99e Initial load
duke
parents:
diff changeset
5519
a61af66fc99e Initial load
duke
parents:
diff changeset
5520 // Look at the alignment of the starting offsets.
a61af66fc99e Initial load
duke
parents:
diff changeset
5521 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
5522
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5523 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
5524 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
5525 if (src_off_con < 0 || dest_off_con < 0)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5526 // At present, we can only understand constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
5527 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5528
3742
b2cb497dec28 7047069: Array can dynamically change size when assigned to an object field
kvn
parents: 3337
diff changeset
5529 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
5530 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
5531
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5532 if (((src_off | dest_off) & (BytesPerLong-1)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5533 // Non-aligned; too bad.
a61af66fc99e Initial load
duke
parents:
diff changeset
5534 // One more chance: Pick off an initial 32-bit word.
a61af66fc99e Initial load
duke
parents:
diff changeset
5535 // This is a common case, since abase can be odd mod 8.
a61af66fc99e Initial load
duke
parents:
diff changeset
5536 if (((src_off | dest_off) & (BytesPerLong-1)) == BytesPerInt &&
a61af66fc99e Initial load
duke
parents:
diff changeset
5537 ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5538 Node* sptr = basic_plus_adr(src, src_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5539 Node* dptr = basic_plus_adr(dest, dest_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5540 Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5541 store_to_memory(control(), dptr, sval, T_INT, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5542 src_off += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
5543 dest_off += BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
5544 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5545 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5548 assert(src_off % BytesPerLong == 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5549 assert(dest_off % BytesPerLong == 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5550
a61af66fc99e Initial load
duke
parents:
diff changeset
5551 // Do this copy by giant steps.
a61af66fc99e Initial load
duke
parents:
diff changeset
5552 Node* sptr = basic_plus_adr(src, src_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5553 Node* dptr = basic_plus_adr(dest, dest_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5554 Node* countx = dest_size;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5555 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
5556 countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5557
a61af66fc99e Initial load
duke
parents:
diff changeset
5558 bool disjoint_bases = true; // since alloc != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
5559 generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5560 sptr, NULL, dptr, NULL, countx, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5561
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5564
a61af66fc99e Initial load
duke
parents:
diff changeset
5565
a61af66fc99e Initial load
duke
parents:
diff changeset
5566 // Helper function; generates code for the slow case.
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 // We make a call to a runtime method which emulates the native method,
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 // but without the native wrapper overhead.
a61af66fc99e Initial load
duke
parents:
diff changeset
5569 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5570 LibraryCallKit::generate_slow_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5571 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5573 Node* copy_length, bool dest_uninitialized) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5574 assert(!dest_uninitialized, "Invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5575 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON,
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 OptoRuntime::slow_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5577 OptoRuntime::slow_arraycopy_Java(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5578 "slow_arraycopy", adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5579 src, src_offset, dest, dest_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5580 copy_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
5581
a61af66fc99e Initial load
duke
parents:
diff changeset
5582 // Handle exceptions thrown by this fellow:
a61af66fc99e Initial load
duke
parents:
diff changeset
5583 make_slow_call_ex(call, env()->Throwable_klass(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
5584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5585
a61af66fc99e Initial load
duke
parents:
diff changeset
5586 // Helper function; generates code for cases requiring runtime checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
5587 Node*
a61af66fc99e Initial load
duke
parents:
diff changeset
5588 LibraryCallKit::generate_checkcast_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5589 Node* dest_elem_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
5590 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5591 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5592 Node* copy_length, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5593 if (stopped()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5594
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5595 address copyfunc_addr = StubRoutines::checkcast_arraycopy(dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5596 if (copyfunc_addr == NULL) { // Stub was not generated, go slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
5597 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5599
a61af66fc99e Initial load
duke
parents:
diff changeset
5600 // Pick out the parameters required to perform a store-check
a61af66fc99e Initial load
duke
parents:
diff changeset
5601 // for the target array. This is an optimistic check. It will
a61af66fc99e Initial load
duke
parents:
diff changeset
5602 // look in each non-null element's class, at the desired klass's
a61af66fc99e Initial load
duke
parents:
diff changeset
5603 // 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
5604 int sco_offset = in_bytes(Klass::super_check_offset_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5605 Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5606 Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
1844
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1748
diff changeset
5607 Node* check_offset = ConvI2X(_gvn.transform(n3));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5608 Node* check_value = dest_elem_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
5609
a61af66fc99e Initial load
duke
parents:
diff changeset
5610 Node* src_start = array_element_address(src, src_offset, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 Node* dest_start = array_element_address(dest, dest_offset, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
5612
a61af66fc99e Initial load
duke
parents:
diff changeset
5613 // (We know the arrays are never conjoint, because their types differ.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5614 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5615 OptoRuntime::checkcast_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5616 copyfunc_addr, "checkcast_arraycopy", adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5617 // five arguments, of which two are
a61af66fc99e Initial load
duke
parents:
diff changeset
5618 // intptr_t (jlong in LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 src_start, dest_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
5620 copy_length XTOP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5621 check_offset XTOP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 check_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
5623
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5624 return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5626
a61af66fc99e Initial load
duke
parents:
diff changeset
5627
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 // Helper function; generates code for cases requiring runtime checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 Node*
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 LibraryCallKit::generate_generic_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5631 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5632 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5633 Node* copy_length, bool dest_uninitialized) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5634 assert(!dest_uninitialized, "Invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5635 if (stopped()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5636 address copyfunc_addr = StubRoutines::generic_arraycopy();
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 if (copyfunc_addr == NULL) { // Stub was not generated, go slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
5638 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5640
a61af66fc99e Initial load
duke
parents:
diff changeset
5641 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5642 OptoRuntime::generic_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5643 copyfunc_addr, "generic_arraycopy", adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5644 src, src_offset, dest, dest_offset, copy_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
5645
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6795
diff changeset
5646 return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5648
a61af66fc99e Initial load
duke
parents:
diff changeset
5649 // Helper function; generates the fast out-of-line call to an arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5651 LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5652 BasicType basic_elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 bool disjoint_bases,
a61af66fc99e Initial load
duke
parents:
diff changeset
5654 Node* src, Node* src_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5655 Node* dest, Node* dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5656 Node* copy_length, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5657 if (stopped()) return; // nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
5658
a61af66fc99e Initial load
duke
parents:
diff changeset
5659 Node* src_start = src;
a61af66fc99e Initial load
duke
parents:
diff changeset
5660 Node* dest_start = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
5661 if (src_offset != NULL || dest_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5662 assert(src_offset != NULL && dest_offset != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
5663 src_start = array_element_address(src, src_offset, basic_elem_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5664 dest_start = array_element_address(dest, dest_offset, basic_elem_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
5665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5666
a61af66fc99e Initial load
duke
parents:
diff changeset
5667 // Figure out which arraycopy runtime method to call.
a61af66fc99e Initial load
duke
parents:
diff changeset
5668 const char* copyfunc_name = "arraycopy";
a61af66fc99e Initial load
duke
parents:
diff changeset
5669 address copyfunc_addr =
a61af66fc99e Initial load
duke
parents:
diff changeset
5670 basictype2arraycopy(basic_elem_type, src_offset, dest_offset,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2320
diff changeset
5671 disjoint_bases, copyfunc_name, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5672
a61af66fc99e Initial load
duke
parents:
diff changeset
5673 // Call it. Note that the count_ix value is not scaled to a byte-size.
a61af66fc99e Initial load
duke
parents:
diff changeset
5674 make_runtime_call(RC_LEAF|RC_NO_FP,
a61af66fc99e Initial load
duke
parents:
diff changeset
5675 OptoRuntime::fast_arraycopy_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5676 copyfunc_addr, copyfunc_name, adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
5677 src_start, dest_start, copy_length XTOP);
a61af66fc99e Initial load
duke
parents:
diff changeset
5678 }
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5679
7637
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5680 //-------------inline_encodeISOArray-----------------------------------
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5681 // 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
5682 bool LibraryCallKit::inline_encodeISOArray() {
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5683 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
5684 // 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
5685 Node *src = argument(0);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5686 Node *src_offset = argument(1);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5687 Node *dst = argument(2);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5688 Node *dst_offset = argument(3);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5689 Node *length = argument(4);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5690
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5691 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
5692 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
5693 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
5694 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
5695 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
5696 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
5697 // failed array check
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5698 return false;
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
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5701 // 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
5702 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
5703 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
5704 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
5705 return false;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5706 }
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5707 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
5708 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
5709 // '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
5710 // '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
5711
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5712 const TypeAryPtr* mtype = TypeAryPtr::BYTES;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5713 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
5714 enc = _gvn.transform(enc);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5715 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
5716 set_memory(res_mem, mtype);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5717 set_result(enc);
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5718 return true;
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5719 }
b30b3c2a0cf2 6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents: 7602
diff changeset
5720
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5721 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5722 * Calculate CRC32 for byte.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5723 * 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
5724 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5725 bool LibraryCallKit::inline_updateCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5726 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
5727 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
5728 // no receiver since it is static method
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5729 Node* crc = argument(0); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5730 Node* b = argument(1); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5731
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5732 /*
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5733 * int c = ~ crc;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5734 * b = timesXtoThe32[(b ^ c) & 0xFF];
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5735 * b = b ^ (c >>> 8);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5736 * crc = ~b;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5737 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5738
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5739 Node* M1 = intcon(-1);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5740 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
5741 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
5742 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
5743
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5744 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
5745 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
5746 Node* adr = basic_plus_adr(top(), base, ConvI2X(offset));
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5747 result = make_load(control(), adr, TypeInt::INT, T_INT);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5748
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5749 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
5750 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
5751 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
5752 set_result(result);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5753 return true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5754 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5755
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5756 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5757 * Calculate CRC32 for byte[] array.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5758 * 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
5759 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5760 bool LibraryCallKit::inline_updateBytesCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5761 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
5762 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
5763 // no receiver since it is static method
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5764 Node* crc = argument(0); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5765 Node* src = argument(1); // type: oop
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5766 Node* offset = argument(2); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5767 Node* length = argument(3); // type: int
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 const Type* src_type = src->Value(&_gvn);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5770 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
5771 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
5772 // failed array check
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5773 return false;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5774 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5775
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5776 // 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
5777 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
5778 if (src_elem != T_BYTE) {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5779 return false;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5780 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5781
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5782 // '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
5783 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
5784
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5785 // 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
5786 // 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
5787
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5788 // Call the stub.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5789 address stubAddr = StubRoutines::updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5790 const char *stubName = "updateBytesCRC32";
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5791
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5792 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
5793 stubAddr, stubName, TypePtr::BOTTOM,
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5794 crc, src_start, length);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5795 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
5796 set_result(result);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5797 return true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5798 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5799
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 * Calculate CRC32 for ByteBuffer.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5802 * 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
5803 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5804 bool LibraryCallKit::inline_updateByteBufferCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5805 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
5806 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
5807 // no receiver since it is static method
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5808 Node* crc = argument(0); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5809 Node* src = argument(1); // type: long
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5810 Node* offset = argument(3); // type: int
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5811 Node* length = argument(4); // type: int
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 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
5814 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
5815 offset = ConvI2X(offset);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5816
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5817 // '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
5818 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
5819
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5820 // Call the stub.
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5821 address stubAddr = StubRoutines::updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5822 const char *stubName = "updateBytesCRC32";
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5823
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5824 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
5825 stubAddr, stubName, TypePtr::BOTTOM,
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5826 crc, src_start, length);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5827 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
5828 set_result(result);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5829 return true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5830 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10405
diff changeset
5831
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5832 //----------------------------inline_reference_get----------------------------
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5833 // 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
5834 bool LibraryCallKit::inline_reference_get() {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5835 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
5836 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
5837
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5838 // Get the argument:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5839 Node* reference_obj = null_check_receiver();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5840 if (stopped()) return true;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5841
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5842 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
5843
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5844 ciInstanceKlass* klass = env()->Object_klass();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5845 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
5846
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5847 Node* no_ctrl = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5848 Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5849
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5850 // 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
5851 pre_barrier(false /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5852 control(),
3258
edd9b016deb6 7036021: G1: build failure on win64 and linux with hs21 in jdk6 build environment
johnc
parents: 3255
diff changeset
5853 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
5854 result /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5855 T_OBJECT);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5856
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
5857 // 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
5858 // 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
5859 insert_mem_bar(Op_MemBarCPUOrder);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
5860
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5861 set_result(result);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5862 return true;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2385
diff changeset
5863 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5864
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5865
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5866 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
5867 bool is_exact=true, bool is_static=false) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5868
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5869 const TypeInstPtr* tinst = _gvn.type(fromObj)->isa_instptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5870 assert(tinst != NULL, "obj is null");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5871 assert(tinst->klass()->is_loaded(), "obj is not loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5872 assert(!is_exact || tinst->klass_is_exact(), "klass not exact");
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 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
5875 ciSymbol::make(fieldTypeString),
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5876 is_static);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5877 if (field == NULL) return (Node *) NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5878 assert (field != NULL, "undefined field");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5879
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5880 // Next code copied from Parse::do_get_xxx():
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5881
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5882 // Compute address and memory type.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5883 int offset = field->offset_in_bytes();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5884 bool is_vol = field->is_volatile();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5885 ciType* field_klass = field->type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5886 assert(field_klass->is_loaded(), "should be loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5887 const TypePtr* adr_type = C->alias_type(field)->adr_type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5888 Node *adr = basic_plus_adr(fromObj, fromObj, offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5889 BasicType bt = field->layout_type();
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 // Build the resultant type of the load
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5892 const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5893
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5894 // Build the load.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5895 Node* loadedField = make_load(NULL, adr, type, bt, adr_type, is_vol);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5896 return loadedField;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5897 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5898
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 //------------------------------inline_aescrypt_Block-----------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5901 bool LibraryCallKit::inline_aescrypt_Block(vmIntrinsics::ID id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5902 address stubAddr;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5903 const char *stubName;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5904 assert(UseAES, "need AES instruction support");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5905
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5906 switch(id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5907 case vmIntrinsics::_aescrypt_encryptBlock:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5908 stubAddr = StubRoutines::aescrypt_encryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5909 stubName = "aescrypt_encryptBlock";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5910 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5911 case vmIntrinsics::_aescrypt_decryptBlock:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5912 stubAddr = StubRoutines::aescrypt_decryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5913 stubName = "aescrypt_decryptBlock";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5914 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5915 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5916 if (stubAddr == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5917
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5918 Node* aescrypt_object = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5919 Node* src = argument(1);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5920 Node* src_offset = argument(2);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5921 Node* dest = argument(3);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5922 Node* dest_offset = argument(4);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5923
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5924 // (1) src and dest are arrays.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5925 const Type* src_type = src->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5926 const Type* dest_type = dest->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5927 const TypeAryPtr* top_src = src_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5928 const TypeAryPtr* top_dest = dest_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5929 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
5930
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5931 // 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
5932 // we are just trying to get the call to be generated.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5933 Node* src_start = src;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5934 Node* dest_start = dest;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5935 if (src_offset != NULL || dest_offset != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5936 assert(src_offset != NULL && dest_offset != NULL, "");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5937 src_start = array_element_address(src, src_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5938 dest_start = array_element_address(dest, dest_offset, T_BYTE);
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
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5941 // now need to get the start of its expanded key array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5942 // 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
5943 Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5944 if (k_start == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5945
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5946 if (Matcher::pass_original_key_for_aes()) {
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5947 // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5948 // compatibility issues between Java key expansion and SPARC crypto instructions
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5949 Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5950 if (original_k_start == NULL) return false;
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5951
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5952 // Call the stub.
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5953 make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5954 stubAddr, stubName, TypePtr::BOTTOM,
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5955 src_start, dest_start, k_start, original_k_start);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5956 } else {
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5957 // Call the stub.
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5958 make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5959 stubAddr, stubName, TypePtr::BOTTOM,
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5960 src_start, dest_start, k_start);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
5961 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5962
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5963 return true;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5964 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5965
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5966 //------------------------------inline_cipherBlockChaining_AESCrypt-----------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5967 bool LibraryCallKit::inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5968 address stubAddr;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5969 const char *stubName;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5970
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5971 assert(UseAES, "need AES instruction support");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5972
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5973 switch(id) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5974 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5975 stubAddr = StubRoutines::cipherBlockChaining_encryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5976 stubName = "cipherBlockChaining_encryptAESCrypt";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5977 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5978 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5979 stubAddr = StubRoutines::cipherBlockChaining_decryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5980 stubName = "cipherBlockChaining_decryptAESCrypt";
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5981 break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5982 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5983 if (stubAddr == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5984
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5985 Node* cipherBlockChaining_object = argument(0);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5986 Node* src = argument(1);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5987 Node* src_offset = argument(2);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5988 Node* len = argument(3);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5989 Node* dest = argument(4);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
5990 Node* dest_offset = argument(5);
6894
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 // (1) src and dest are arrays.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5993 const Type* src_type = src->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5994 const Type* dest_type = dest->Value(&_gvn);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5995 const TypeAryPtr* top_src = src_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5996 const TypeAryPtr* top_dest = dest_type->isa_aryptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5997 assert (top_src != NULL && top_src->klass() != NULL
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5998 && top_dest != NULL && top_dest->klass() != NULL, "args are strange");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
5999
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6000 // checks are the responsibility of the caller
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6001 Node* src_start = src;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6002 Node* dest_start = dest;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6003 if (src_offset != NULL || dest_offset != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6004 assert(src_offset != NULL && dest_offset != NULL, "");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6005 src_start = array_element_address(src, src_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6006 dest_start = array_element_address(dest, dest_offset, T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6007 }
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 // 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
6010 // (because of the predicated logic executed earlier).
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6011 // so we cast it here safely.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6012 // 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
6013
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6014 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
6015 if (embeddedCipherObj == NULL) return false;
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 // cast it to what we know it will be at runtime
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6018 const TypeInstPtr* tinst = _gvn.type(cipherBlockChaining_object)->isa_instptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6019 assert(tinst != NULL, "CBC obj is null");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6020 assert(tinst->klass()->is_loaded(), "CBC obj is not loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6021 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
6022 if (!klass_AESCrypt->is_loaded()) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6023
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6024 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6025 const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6026 const TypeOopPtr* xtype = aklass->as_instance_type();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6027 Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6028 aescrypt_object = _gvn.transform(aescrypt_object);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6029
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6030 // 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
6031 Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6032 if (k_start == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6033
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6034 // similarly, get the start address of the r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6035 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
6036 if (objRvec == NULL) return false;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6037 Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6038
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6039 Node* cbcCrypt;
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6040 if (Matcher::pass_original_key_for_aes()) {
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6041 // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6042 // compatibility issues between Java key expansion and SPARC crypto instructions
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6043 Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6044 if (original_k_start == NULL) return false;
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6045
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6046 // Call the stub, passing src_start, dest_start, k_start, r_start, src_len and original_k_start
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6047 cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6048 OptoRuntime::cipherBlockChaining_aescrypt_Type(),
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6049 stubAddr, stubName, TypePtr::BOTTOM,
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6050 src_start, dest_start, k_start, r_start, len, original_k_start);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6051 } else {
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6052 // Call the stub, passing src_start, dest_start, k_start, r_start and src_len
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6053 cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6054 OptoRuntime::cipherBlockChaining_aescrypt_Type(),
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6055 stubAddr, stubName, TypePtr::BOTTOM,
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6056 src_start, dest_start, k_start, r_start, len);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6057 }
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6058
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6059 // return cipher length (int)
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6060 Node* retvalue = _gvn.transform(new (C) ProjNode(cbcCrypt, TypeFunc::Parms));
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6061 set_result(retvalue);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6062 return true;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6063 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6064
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6065 //------------------------------get_key_start_from_aescrypt_object-----------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6066 Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6067 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
6068 assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6069 if (objAESCryptKey == NULL) return (Node *) NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6070
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6071 // 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
6072 Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6073 return k_start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6074 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6075
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6076 //------------------------------get_original_key_start_from_aescrypt_object-----------------------
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6077 Node * LibraryCallKit::get_original_key_start_from_aescrypt_object(Node *aescrypt_object) {
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6078 Node* objAESCryptKey = load_field_from_object(aescrypt_object, "lastKey", "[B", /*is_exact*/ false);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6079 assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6080 if (objAESCryptKey == NULL) return (Node *) NULL;
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6081
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6082 // now have the array, need to get the start address of the lastKey array
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6083 Node* original_k_start = array_element_address(objAESCryptKey, intcon(0), T_BYTE);
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6084 return original_k_start;
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6085 }
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 13019
diff changeset
6086
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6087 //----------------------------inline_cipherBlockChaining_AESCrypt_predicate----------------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6088 // Return node representing slow path of predicate check.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6089 // the pseudo code we want to emulate with this predicate is:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6090 // for encryption:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6091 // if (embeddedCipherObj instanceof AESCrypt) do_intrinsic, else do_javapath
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6092 // for decryption:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6093 // if ((embeddedCipherObj instanceof AESCrypt) && (cipher!=plain)) do_intrinsic, else do_javapath
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6094 // 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
6095 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6096 Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6097 // First, check receiver for NULL since it is virtual method.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6098 Node* objCBC = argument(0);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
6099 objCBC = null_check(objCBC);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6100
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6101 if (stopped()) return NULL; // Always NULL
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6102
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6103 // Load embeddedCipher field of CipherBlockChaining object.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6104 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
6105
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6106 // get AESCrypt klass for instanceOf check
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6107 // 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
6108 // will have same classloader as CipherBlockChaining object
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6109 const TypeInstPtr* tinst = _gvn.type(objCBC)->isa_instptr();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6110 assert(tinst != NULL, "CBCobj is null");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6111 assert(tinst->klass()->is_loaded(), "CBCobj is not loaded");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6112
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6113 // we want to do an instanceof comparison against the AESCrypt class
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6114 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
6115 if (!klass_AESCrypt->is_loaded()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6116 // 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
6117 Node* ctrl = control();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6118 set_control(top()); // no regular fast path
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6119 return ctrl;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6120 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6121 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6122
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6123 Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6124 Node* cmp_instof = _gvn.transform(new (C) CmpINode(instof, intcon(1)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6125 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
6126
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6127 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6128
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6129 // for encryption, we are done
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6130 if (!decrypting)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6131 return instof_false; // even if it is NULL
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6132
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6133 // for decryption, we need to add a further check to avoid
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6134 // taking the intrinsic path when cipher and plain are the same
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6135 // see the original java code for why.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6136 RegionNode* region = new(C) RegionNode(3);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6137 region->init_req(1, instof_false);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6138 Node* src = argument(1);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
6139 Node* dest = argument(4);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6140 Node* cmp_src_dest = _gvn.transform(new (C) CmpPNode(src, dest));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6141 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
6142 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
6143 region->init_req(2, src_dest_conjoint);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6144
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6145 record_for_igvn(region);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6146 return _gvn.transform(region);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6888
diff changeset
6147 }