Mercurial > hg > truffle
annotate src/share/vm/opto/library_call.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 4311f23817fd |
children | 4b29a725c43c |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
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 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_library_call.cpp.incl" | |
27 | |
28 class LibraryIntrinsic : public InlineCallGenerator { | |
29 // Extend the set of intrinsics known to the runtime: | |
30 public: | |
31 private: | |
32 bool _is_virtual; | |
33 vmIntrinsics::ID _intrinsic_id; | |
34 | |
35 public: | |
36 LibraryIntrinsic(ciMethod* m, bool is_virtual, vmIntrinsics::ID id) | |
37 : InlineCallGenerator(m), | |
38 _is_virtual(is_virtual), | |
39 _intrinsic_id(id) | |
40 { | |
41 } | |
42 virtual bool is_intrinsic() const { return true; } | |
43 virtual bool is_virtual() const { return _is_virtual; } | |
44 virtual JVMState* generate(JVMState* jvms); | |
45 vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; } | |
46 }; | |
47 | |
48 | |
49 // Local helper class for LibraryIntrinsic: | |
50 class LibraryCallKit : public GraphKit { | |
51 private: | |
52 LibraryIntrinsic* _intrinsic; // the library intrinsic being called | |
53 | |
54 public: | |
55 LibraryCallKit(JVMState* caller, LibraryIntrinsic* intrinsic) | |
56 : GraphKit(caller), | |
57 _intrinsic(intrinsic) | |
58 { | |
59 } | |
60 | |
61 ciMethod* caller() const { return jvms()->method(); } | |
62 int bci() const { return jvms()->bci(); } | |
63 LibraryIntrinsic* intrinsic() const { return _intrinsic; } | |
64 vmIntrinsics::ID intrinsic_id() const { return _intrinsic->intrinsic_id(); } | |
65 ciMethod* callee() const { return _intrinsic->method(); } | |
66 ciSignature* signature() const { return callee()->signature(); } | |
67 int arg_size() const { return callee()->arg_size(); } | |
68 | |
69 bool try_to_inline(); | |
70 | |
71 // Helper functions to inline natives | |
72 void push_result(RegionNode* region, PhiNode* value); | |
73 Node* generate_guard(Node* test, RegionNode* region, float true_prob); | |
74 Node* generate_slow_guard(Node* test, RegionNode* region); | |
75 Node* generate_fair_guard(Node* test, RegionNode* region); | |
76 Node* generate_negative_guard(Node* index, RegionNode* region, | |
77 // resulting CastII of index: | |
78 Node* *pos_index = NULL); | |
79 Node* generate_nonpositive_guard(Node* index, bool never_negative, | |
80 // resulting CastII of index: | |
81 Node* *pos_index = NULL); | |
82 Node* generate_limit_guard(Node* offset, Node* subseq_length, | |
83 Node* array_length, | |
84 RegionNode* region); | |
85 Node* generate_current_thread(Node* &tls_output); | |
86 address basictype2arraycopy(BasicType t, Node *src_offset, Node *dest_offset, | |
87 bool disjoint_bases, const char* &name); | |
88 Node* load_mirror_from_klass(Node* klass); | |
89 Node* load_klass_from_mirror_common(Node* mirror, bool never_see_null, | |
90 int nargs, | |
91 RegionNode* region, int null_path, | |
92 int offset); | |
93 Node* load_klass_from_mirror(Node* mirror, bool never_see_null, int nargs, | |
94 RegionNode* region, int null_path) { | |
95 int offset = java_lang_Class::klass_offset_in_bytes(); | |
96 return load_klass_from_mirror_common(mirror, never_see_null, nargs, | |
97 region, null_path, | |
98 offset); | |
99 } | |
100 Node* load_array_klass_from_mirror(Node* mirror, bool never_see_null, | |
101 int nargs, | |
102 RegionNode* region, int null_path) { | |
103 int offset = java_lang_Class::array_klass_offset_in_bytes(); | |
104 return load_klass_from_mirror_common(mirror, never_see_null, nargs, | |
105 region, null_path, | |
106 offset); | |
107 } | |
108 Node* generate_access_flags_guard(Node* kls, | |
109 int modifier_mask, int modifier_bits, | |
110 RegionNode* region); | |
111 Node* generate_interface_guard(Node* kls, RegionNode* region); | |
112 Node* generate_array_guard(Node* kls, RegionNode* region) { | |
113 return generate_array_guard_common(kls, region, false, false); | |
114 } | |
115 Node* generate_non_array_guard(Node* kls, RegionNode* region) { | |
116 return generate_array_guard_common(kls, region, false, true); | |
117 } | |
118 Node* generate_objArray_guard(Node* kls, RegionNode* region) { | |
119 return generate_array_guard_common(kls, region, true, false); | |
120 } | |
121 Node* generate_non_objArray_guard(Node* kls, RegionNode* region) { | |
122 return generate_array_guard_common(kls, region, true, true); | |
123 } | |
124 Node* generate_array_guard_common(Node* kls, RegionNode* region, | |
125 bool obj_array, bool not_array); | |
126 Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region); | |
127 CallJavaNode* generate_method_call(vmIntrinsics::ID method_id, | |
128 bool is_virtual = false, bool is_static = false); | |
129 CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) { | |
130 return generate_method_call(method_id, false, true); | |
131 } | |
132 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) { | |
133 return generate_method_call(method_id, true, false); | |
134 } | |
135 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
136 Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2); |
0 | 137 bool inline_string_compareTo(); |
138 bool inline_string_indexOf(); | |
139 Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i); | |
681 | 140 bool inline_string_equals(); |
0 | 141 Node* pop_math_arg(); |
142 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName); | |
143 bool inline_math_native(vmIntrinsics::ID id); | |
144 bool inline_trig(vmIntrinsics::ID id); | |
145 bool inline_trans(vmIntrinsics::ID id); | |
146 bool inline_abs(vmIntrinsics::ID id); | |
147 bool inline_sqrt(vmIntrinsics::ID id); | |
148 bool inline_pow(vmIntrinsics::ID id); | |
149 bool inline_exp(vmIntrinsics::ID id); | |
150 bool inline_min_max(vmIntrinsics::ID id); | |
151 Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y); | |
152 // This returns Type::AnyPtr, RawPtr, or OopPtr. | |
153 int classify_unsafe_addr(Node* &base, Node* &offset); | |
154 Node* make_unsafe_address(Node* base, Node* offset); | |
155 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile); | |
156 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static); | |
157 bool inline_unsafe_allocate(); | |
158 bool inline_unsafe_copyMemory(); | |
159 bool inline_native_currentThread(); | |
160 bool inline_native_time_funcs(bool isNano); | |
161 bool inline_native_isInterrupted(); | |
162 bool inline_native_Class_query(vmIntrinsics::ID id); | |
163 bool inline_native_subtype_check(); | |
164 | |
165 bool inline_native_newArray(); | |
166 bool inline_native_getLength(); | |
167 bool inline_array_copyOf(bool is_copyOfRange); | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
168 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
|
169 void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark); |
0 | 170 bool inline_native_clone(bool is_virtual); |
171 bool inline_native_Reflection_getCallerClass(); | |
172 bool inline_native_AtomicLong_get(); | |
173 bool inline_native_AtomicLong_attemptUpdate(); | |
174 bool is_method_invoke_or_aux_frame(JVMState* jvms); | |
175 // Helper function for inlining native object hash method | |
176 bool inline_native_hashcode(bool is_virtual, bool is_static); | |
177 bool inline_native_getClass(); | |
178 | |
179 // Helper functions for inlining arraycopy | |
180 bool inline_arraycopy(); | |
181 void generate_arraycopy(const TypePtr* adr_type, | |
182 BasicType basic_elem_type, | |
183 Node* src, Node* src_offset, | |
184 Node* dest, Node* dest_offset, | |
185 Node* copy_length, | |
186 bool disjoint_bases = false, | |
187 bool length_never_negative = false, | |
188 RegionNode* slow_region = NULL); | |
189 AllocateArrayNode* tightly_coupled_allocation(Node* ptr, | |
190 RegionNode* slow_region); | |
191 void generate_clear_array(const TypePtr* adr_type, | |
192 Node* dest, | |
193 BasicType basic_elem_type, | |
194 Node* slice_off, | |
195 Node* slice_len, | |
196 Node* slice_end); | |
197 bool generate_block_arraycopy(const TypePtr* adr_type, | |
198 BasicType basic_elem_type, | |
199 AllocateNode* alloc, | |
200 Node* src, Node* src_offset, | |
201 Node* dest, Node* dest_offset, | |
202 Node* dest_size); | |
203 void generate_slow_arraycopy(const TypePtr* adr_type, | |
204 Node* src, Node* src_offset, | |
205 Node* dest, Node* dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
206 Node* copy_length); |
0 | 207 Node* generate_checkcast_arraycopy(const TypePtr* adr_type, |
208 Node* dest_elem_klass, | |
209 Node* src, Node* src_offset, | |
210 Node* dest, Node* dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
211 Node* copy_length); |
0 | 212 Node* generate_generic_arraycopy(const TypePtr* adr_type, |
213 Node* src, Node* src_offset, | |
214 Node* dest, Node* dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
215 Node* copy_length); |
0 | 216 void generate_unchecked_arraycopy(const TypePtr* adr_type, |
217 BasicType basic_elem_type, | |
218 bool disjoint_bases, | |
219 Node* src, Node* src_offset, | |
220 Node* dest, Node* dest_offset, | |
221 Node* copy_length); | |
222 bool inline_unsafe_CAS(BasicType type); | |
223 bool inline_unsafe_ordered_store(BasicType type); | |
224 bool inline_fp_conversions(vmIntrinsics::ID id); | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
225 bool inline_numberOfLeadingZeros(vmIntrinsics::ID id); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
226 bool inline_numberOfTrailingZeros(vmIntrinsics::ID id); |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
227 bool inline_bitCount(vmIntrinsics::ID id); |
0 | 228 bool inline_reverseBytes(vmIntrinsics::ID id); |
229 }; | |
230 | |
231 | |
232 //---------------------------make_vm_intrinsic---------------------------- | |
233 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { | |
234 vmIntrinsics::ID id = m->intrinsic_id(); | |
235 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); | |
236 | |
237 if (DisableIntrinsic[0] != '\0' | |
238 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) { | |
239 // disabled by a user request on the command line: | |
240 // example: -XX:DisableIntrinsic=_hashCode,_getClass | |
241 return NULL; | |
242 } | |
243 | |
244 if (!m->is_loaded()) { | |
245 // do not attempt to inline unloaded methods | |
246 return NULL; | |
247 } | |
248 | |
249 // Only a few intrinsics implement a virtual dispatch. | |
250 // They are expensive calls which are also frequently overridden. | |
251 if (is_virtual) { | |
252 switch (id) { | |
253 case vmIntrinsics::_hashCode: | |
254 case vmIntrinsics::_clone: | |
255 // OK, Object.hashCode and Object.clone intrinsics come in both flavors | |
256 break; | |
257 default: | |
258 return NULL; | |
259 } | |
260 } | |
261 | |
262 // -XX:-InlineNatives disables nearly all intrinsics: | |
263 if (!InlineNatives) { | |
264 switch (id) { | |
265 case vmIntrinsics::_indexOf: | |
266 case vmIntrinsics::_compareTo: | |
681 | 267 case vmIntrinsics::_equals: |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
268 case vmIntrinsics::_equalsC: |
0 | 269 break; // InlineNatives does not control String.compareTo |
270 default: | |
271 return NULL; | |
272 } | |
273 } | |
274 | |
275 switch (id) { | |
276 case vmIntrinsics::_compareTo: | |
277 if (!SpecialStringCompareTo) return NULL; | |
278 break; | |
279 case vmIntrinsics::_indexOf: | |
280 if (!SpecialStringIndexOf) return NULL; | |
281 break; | |
681 | 282 case vmIntrinsics::_equals: |
283 if (!SpecialStringEquals) return NULL; | |
284 break; | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
285 case vmIntrinsics::_equalsC: |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
286 if (!SpecialArraysEquals) return NULL; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
287 break; |
0 | 288 case vmIntrinsics::_arraycopy: |
289 if (!InlineArrayCopy) return NULL; | |
290 break; | |
291 case vmIntrinsics::_copyMemory: | |
292 if (StubRoutines::unsafe_arraycopy() == NULL) return NULL; | |
293 if (!InlineArrayCopy) return NULL; | |
294 break; | |
295 case vmIntrinsics::_hashCode: | |
296 if (!InlineObjectHash) return NULL; | |
297 break; | |
298 case vmIntrinsics::_clone: | |
299 case vmIntrinsics::_copyOf: | |
300 case vmIntrinsics::_copyOfRange: | |
301 if (!InlineObjectCopy) return NULL; | |
302 // These also use the arraycopy intrinsic mechanism: | |
303 if (!InlineArrayCopy) return NULL; | |
304 break; | |
305 case vmIntrinsics::_checkIndex: | |
306 // We do not intrinsify this. The optimizer does fine with it. | |
307 return NULL; | |
308 | |
309 case vmIntrinsics::_get_AtomicLong: | |
310 case vmIntrinsics::_attemptUpdate: | |
311 if (!InlineAtomicLong) return NULL; | |
312 break; | |
313 | |
314 case vmIntrinsics::_getCallerClass: | |
315 if (!UseNewReflection) return NULL; | |
316 if (!InlineReflectionGetCallerClass) return NULL; | |
317 if (!JDK_Version::is_gte_jdk14x_version()) return NULL; | |
318 break; | |
319 | |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
320 case vmIntrinsics::_bitCount_i: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
321 case vmIntrinsics::_bitCount_l: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
322 if (!UsePopCountInstruction) return NULL; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
323 break; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
324 |
0 | 325 default: |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
851
diff
changeset
|
326 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
|
327 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); |
0 | 328 break; |
329 } | |
330 | |
331 // -XX:-InlineClassNatives disables natives from the Class class. | |
332 // The flag applies to all reflective calls, notably Array.newArray | |
333 // (visible to Java programmers as Array.newInstance). | |
334 if (m->holder()->name() == ciSymbol::java_lang_Class() || | |
335 m->holder()->name() == ciSymbol::java_lang_reflect_Array()) { | |
336 if (!InlineClassNatives) return NULL; | |
337 } | |
338 | |
339 // -XX:-InlineThreadNatives disables natives from the Thread class. | |
340 if (m->holder()->name() == ciSymbol::java_lang_Thread()) { | |
341 if (!InlineThreadNatives) return NULL; | |
342 } | |
343 | |
344 // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes. | |
345 if (m->holder()->name() == ciSymbol::java_lang_Math() || | |
346 m->holder()->name() == ciSymbol::java_lang_Float() || | |
347 m->holder()->name() == ciSymbol::java_lang_Double()) { | |
348 if (!InlineMathNatives) return NULL; | |
349 } | |
350 | |
351 // -XX:-InlineUnsafeOps disables natives from the Unsafe class. | |
352 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) { | |
353 if (!InlineUnsafeOps) return NULL; | |
354 } | |
355 | |
356 return new LibraryIntrinsic(m, is_virtual, (vmIntrinsics::ID) id); | |
357 } | |
358 | |
359 //----------------------register_library_intrinsics----------------------- | |
360 // Initialize this file's data structures, for each Compile instance. | |
361 void Compile::register_library_intrinsics() { | |
362 // Nothing to do here. | |
363 } | |
364 | |
365 JVMState* LibraryIntrinsic::generate(JVMState* jvms) { | |
366 LibraryCallKit kit(jvms, this); | |
367 Compile* C = kit.C; | |
368 int nodes = C->unique(); | |
369 #ifndef PRODUCT | |
370 if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { | |
371 char buf[1000]; | |
372 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); | |
373 tty->print_cr("Intrinsic %s", str); | |
374 } | |
375 #endif | |
376 if (kit.try_to_inline()) { | |
377 if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { | |
378 tty->print("Inlining intrinsic %s%s at bci:%d in", | |
379 vmIntrinsics::name_at(intrinsic_id()), | |
380 (is_virtual() ? " (virtual)" : ""), kit.bci()); | |
381 kit.caller()->print_short_name(tty); | |
382 tty->print_cr(" (%d bytes)", kit.caller()->code_size()); | |
383 } | |
384 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); | |
385 if (C->log()) { | |
386 C->log()->elem("intrinsic id='%s'%s nodes='%d'", | |
387 vmIntrinsics::name_at(intrinsic_id()), | |
388 (is_virtual() ? " virtual='1'" : ""), | |
389 C->unique() - nodes); | |
390 } | |
391 return kit.transfer_exceptions_into_jvms(); | |
392 } | |
393 | |
394 if (PrintIntrinsics) { | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
851
diff
changeset
|
395 tty->print("Did not inline intrinsic %s%s at bci:%d in", |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
851
diff
changeset
|
396 vmIntrinsics::name_at(intrinsic_id()), |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
851
diff
changeset
|
397 (is_virtual() ? " (virtual)" : ""), kit.bci()); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
851
diff
changeset
|
398 kit.caller()->print_short_name(tty); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
851
diff
changeset
|
399 tty->print_cr(" (%d bytes)", kit.caller()->code_size()); |
0 | 400 } |
401 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); | |
402 return NULL; | |
403 } | |
404 | |
405 bool LibraryCallKit::try_to_inline() { | |
406 // Handle symbolic names for otherwise undistinguished boolean switches: | |
407 const bool is_store = true; | |
408 const bool is_native_ptr = true; | |
409 const bool is_static = true; | |
410 | |
411 switch (intrinsic_id()) { | |
412 case vmIntrinsics::_hashCode: | |
413 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static); | |
414 case vmIntrinsics::_identityHashCode: | |
415 return inline_native_hashcode(/*!virtual*/ false, is_static); | |
416 case vmIntrinsics::_getClass: | |
417 return inline_native_getClass(); | |
418 | |
419 case vmIntrinsics::_dsin: | |
420 case vmIntrinsics::_dcos: | |
421 case vmIntrinsics::_dtan: | |
422 case vmIntrinsics::_dabs: | |
423 case vmIntrinsics::_datan2: | |
424 case vmIntrinsics::_dsqrt: | |
425 case vmIntrinsics::_dexp: | |
426 case vmIntrinsics::_dlog: | |
427 case vmIntrinsics::_dlog10: | |
428 case vmIntrinsics::_dpow: | |
429 return inline_math_native(intrinsic_id()); | |
430 | |
431 case vmIntrinsics::_min: | |
432 case vmIntrinsics::_max: | |
433 return inline_min_max(intrinsic_id()); | |
434 | |
435 case vmIntrinsics::_arraycopy: | |
436 return inline_arraycopy(); | |
437 | |
438 case vmIntrinsics::_compareTo: | |
439 return inline_string_compareTo(); | |
440 case vmIntrinsics::_indexOf: | |
441 return inline_string_indexOf(); | |
681 | 442 case vmIntrinsics::_equals: |
443 return inline_string_equals(); | |
0 | 444 |
445 case vmIntrinsics::_getObject: | |
446 return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, false); | |
447 case vmIntrinsics::_getBoolean: | |
448 return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, false); | |
449 case vmIntrinsics::_getByte: | |
450 return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, false); | |
451 case vmIntrinsics::_getShort: | |
452 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, false); | |
453 case vmIntrinsics::_getChar: | |
454 return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, false); | |
455 case vmIntrinsics::_getInt: | |
456 return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, false); | |
457 case vmIntrinsics::_getLong: | |
458 return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, false); | |
459 case vmIntrinsics::_getFloat: | |
460 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, false); | |
461 case vmIntrinsics::_getDouble: | |
462 return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, false); | |
463 | |
464 case vmIntrinsics::_putObject: | |
465 return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, false); | |
466 case vmIntrinsics::_putBoolean: | |
467 return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, false); | |
468 case vmIntrinsics::_putByte: | |
469 return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, false); | |
470 case vmIntrinsics::_putShort: | |
471 return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, false); | |
472 case vmIntrinsics::_putChar: | |
473 return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, false); | |
474 case vmIntrinsics::_putInt: | |
475 return inline_unsafe_access(!is_native_ptr, is_store, T_INT, false); | |
476 case vmIntrinsics::_putLong: | |
477 return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, false); | |
478 case vmIntrinsics::_putFloat: | |
479 return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, false); | |
480 case vmIntrinsics::_putDouble: | |
481 return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, false); | |
482 | |
483 case vmIntrinsics::_getByte_raw: | |
484 return inline_unsafe_access(is_native_ptr, !is_store, T_BYTE, false); | |
485 case vmIntrinsics::_getShort_raw: | |
486 return inline_unsafe_access(is_native_ptr, !is_store, T_SHORT, false); | |
487 case vmIntrinsics::_getChar_raw: | |
488 return inline_unsafe_access(is_native_ptr, !is_store, T_CHAR, false); | |
489 case vmIntrinsics::_getInt_raw: | |
490 return inline_unsafe_access(is_native_ptr, !is_store, T_INT, false); | |
491 case vmIntrinsics::_getLong_raw: | |
492 return inline_unsafe_access(is_native_ptr, !is_store, T_LONG, false); | |
493 case vmIntrinsics::_getFloat_raw: | |
494 return inline_unsafe_access(is_native_ptr, !is_store, T_FLOAT, false); | |
495 case vmIntrinsics::_getDouble_raw: | |
496 return inline_unsafe_access(is_native_ptr, !is_store, T_DOUBLE, false); | |
497 case vmIntrinsics::_getAddress_raw: | |
498 return inline_unsafe_access(is_native_ptr, !is_store, T_ADDRESS, false); | |
499 | |
500 case vmIntrinsics::_putByte_raw: | |
501 return inline_unsafe_access(is_native_ptr, is_store, T_BYTE, false); | |
502 case vmIntrinsics::_putShort_raw: | |
503 return inline_unsafe_access(is_native_ptr, is_store, T_SHORT, false); | |
504 case vmIntrinsics::_putChar_raw: | |
505 return inline_unsafe_access(is_native_ptr, is_store, T_CHAR, false); | |
506 case vmIntrinsics::_putInt_raw: | |
507 return inline_unsafe_access(is_native_ptr, is_store, T_INT, false); | |
508 case vmIntrinsics::_putLong_raw: | |
509 return inline_unsafe_access(is_native_ptr, is_store, T_LONG, false); | |
510 case vmIntrinsics::_putFloat_raw: | |
511 return inline_unsafe_access(is_native_ptr, is_store, T_FLOAT, false); | |
512 case vmIntrinsics::_putDouble_raw: | |
513 return inline_unsafe_access(is_native_ptr, is_store, T_DOUBLE, false); | |
514 case vmIntrinsics::_putAddress_raw: | |
515 return inline_unsafe_access(is_native_ptr, is_store, T_ADDRESS, false); | |
516 | |
517 case vmIntrinsics::_getObjectVolatile: | |
518 return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, true); | |
519 case vmIntrinsics::_getBooleanVolatile: | |
520 return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, true); | |
521 case vmIntrinsics::_getByteVolatile: | |
522 return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, true); | |
523 case vmIntrinsics::_getShortVolatile: | |
524 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, true); | |
525 case vmIntrinsics::_getCharVolatile: | |
526 return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, true); | |
527 case vmIntrinsics::_getIntVolatile: | |
528 return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, true); | |
529 case vmIntrinsics::_getLongVolatile: | |
530 return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, true); | |
531 case vmIntrinsics::_getFloatVolatile: | |
532 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, true); | |
533 case vmIntrinsics::_getDoubleVolatile: | |
534 return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, true); | |
535 | |
536 case vmIntrinsics::_putObjectVolatile: | |
537 return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, true); | |
538 case vmIntrinsics::_putBooleanVolatile: | |
539 return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, true); | |
540 case vmIntrinsics::_putByteVolatile: | |
541 return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, true); | |
542 case vmIntrinsics::_putShortVolatile: | |
543 return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, true); | |
544 case vmIntrinsics::_putCharVolatile: | |
545 return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, true); | |
546 case vmIntrinsics::_putIntVolatile: | |
547 return inline_unsafe_access(!is_native_ptr, is_store, T_INT, true); | |
548 case vmIntrinsics::_putLongVolatile: | |
549 return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, true); | |
550 case vmIntrinsics::_putFloatVolatile: | |
551 return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, true); | |
552 case vmIntrinsics::_putDoubleVolatile: | |
553 return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, true); | |
554 | |
555 case vmIntrinsics::_prefetchRead: | |
556 return inline_unsafe_prefetch(!is_native_ptr, !is_store, !is_static); | |
557 case vmIntrinsics::_prefetchWrite: | |
558 return inline_unsafe_prefetch(!is_native_ptr, is_store, !is_static); | |
559 case vmIntrinsics::_prefetchReadStatic: | |
560 return inline_unsafe_prefetch(!is_native_ptr, !is_store, is_static); | |
561 case vmIntrinsics::_prefetchWriteStatic: | |
562 return inline_unsafe_prefetch(!is_native_ptr, is_store, is_static); | |
563 | |
564 case vmIntrinsics::_compareAndSwapObject: | |
565 return inline_unsafe_CAS(T_OBJECT); | |
566 case vmIntrinsics::_compareAndSwapInt: | |
567 return inline_unsafe_CAS(T_INT); | |
568 case vmIntrinsics::_compareAndSwapLong: | |
569 return inline_unsafe_CAS(T_LONG); | |
570 | |
571 case vmIntrinsics::_putOrderedObject: | |
572 return inline_unsafe_ordered_store(T_OBJECT); | |
573 case vmIntrinsics::_putOrderedInt: | |
574 return inline_unsafe_ordered_store(T_INT); | |
575 case vmIntrinsics::_putOrderedLong: | |
576 return inline_unsafe_ordered_store(T_LONG); | |
577 | |
578 case vmIntrinsics::_currentThread: | |
579 return inline_native_currentThread(); | |
580 case vmIntrinsics::_isInterrupted: | |
581 return inline_native_isInterrupted(); | |
582 | |
583 case vmIntrinsics::_currentTimeMillis: | |
584 return inline_native_time_funcs(false); | |
585 case vmIntrinsics::_nanoTime: | |
586 return inline_native_time_funcs(true); | |
587 case vmIntrinsics::_allocateInstance: | |
588 return inline_unsafe_allocate(); | |
589 case vmIntrinsics::_copyMemory: | |
590 return inline_unsafe_copyMemory(); | |
591 case vmIntrinsics::_newArray: | |
592 return inline_native_newArray(); | |
593 case vmIntrinsics::_getLength: | |
594 return inline_native_getLength(); | |
595 case vmIntrinsics::_copyOf: | |
596 return inline_array_copyOf(false); | |
597 case vmIntrinsics::_copyOfRange: | |
598 return inline_array_copyOf(true); | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
599 case vmIntrinsics::_equalsC: |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
600 return inline_array_equals(); |
0 | 601 case vmIntrinsics::_clone: |
602 return inline_native_clone(intrinsic()->is_virtual()); | |
603 | |
604 case vmIntrinsics::_isAssignableFrom: | |
605 return inline_native_subtype_check(); | |
606 | |
607 case vmIntrinsics::_isInstance: | |
608 case vmIntrinsics::_getModifiers: | |
609 case vmIntrinsics::_isInterface: | |
610 case vmIntrinsics::_isArray: | |
611 case vmIntrinsics::_isPrimitive: | |
612 case vmIntrinsics::_getSuperclass: | |
613 case vmIntrinsics::_getComponentType: | |
614 case vmIntrinsics::_getClassAccessFlags: | |
615 return inline_native_Class_query(intrinsic_id()); | |
616 | |
617 case vmIntrinsics::_floatToRawIntBits: | |
618 case vmIntrinsics::_floatToIntBits: | |
619 case vmIntrinsics::_intBitsToFloat: | |
620 case vmIntrinsics::_doubleToRawLongBits: | |
621 case vmIntrinsics::_doubleToLongBits: | |
622 case vmIntrinsics::_longBitsToDouble: | |
623 return inline_fp_conversions(intrinsic_id()); | |
624 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
625 case vmIntrinsics::_numberOfLeadingZeros_i: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
626 case vmIntrinsics::_numberOfLeadingZeros_l: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
627 return inline_numberOfLeadingZeros(intrinsic_id()); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
628 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
629 case vmIntrinsics::_numberOfTrailingZeros_i: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
630 case vmIntrinsics::_numberOfTrailingZeros_l: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
631 return inline_numberOfTrailingZeros(intrinsic_id()); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
632 |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
633 case vmIntrinsics::_bitCount_i: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
634 case vmIntrinsics::_bitCount_l: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
635 return inline_bitCount(intrinsic_id()); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
636 |
0 | 637 case vmIntrinsics::_reverseBytes_i: |
638 case vmIntrinsics::_reverseBytes_l: | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
639 case vmIntrinsics::_reverseBytes_s: |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
640 case vmIntrinsics::_reverseBytes_c: |
0 | 641 return inline_reverseBytes((vmIntrinsics::ID) intrinsic_id()); |
642 | |
643 case vmIntrinsics::_get_AtomicLong: | |
644 return inline_native_AtomicLong_get(); | |
645 case vmIntrinsics::_attemptUpdate: | |
646 return inline_native_AtomicLong_attemptUpdate(); | |
647 | |
648 case vmIntrinsics::_getCallerClass: | |
649 return inline_native_Reflection_getCallerClass(); | |
650 | |
651 default: | |
652 // If you get here, it may be that someone has added a new intrinsic | |
653 // to the list in vmSymbols.hpp without implementing it here. | |
654 #ifndef PRODUCT | |
655 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { | |
656 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)", | |
657 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id()); | |
658 } | |
659 #endif | |
660 return false; | |
661 } | |
662 } | |
663 | |
664 //------------------------------push_result------------------------------ | |
665 // Helper function for finishing intrinsics. | |
666 void LibraryCallKit::push_result(RegionNode* region, PhiNode* value) { | |
667 record_for_igvn(region); | |
668 set_control(_gvn.transform(region)); | |
669 BasicType value_type = value->type()->basic_type(); | |
670 push_node(value_type, _gvn.transform(value)); | |
671 } | |
672 | |
673 //------------------------------generate_guard--------------------------- | |
674 // Helper function for generating guarded fast-slow graph structures. | |
675 // The given 'test', if true, guards a slow path. If the test fails | |
676 // then a fast path can be taken. (We generally hope it fails.) | |
677 // In all cases, GraphKit::control() is updated to the fast path. | |
678 // The returned value represents the control for the slow path. | |
679 // The return value is never 'top'; it is either a valid control | |
680 // or NULL if it is obvious that the slow path can never be taken. | |
681 // Also, if region and the slow control are not NULL, the slow edge | |
682 // is appended to the region. | |
683 Node* LibraryCallKit::generate_guard(Node* test, RegionNode* region, float true_prob) { | |
684 if (stopped()) { | |
685 // Already short circuited. | |
686 return NULL; | |
687 } | |
688 | |
689 // Build an if node and its projections. | |
690 // If test is true we take the slow path, which we assume is uncommon. | |
691 if (_gvn.type(test) == TypeInt::ZERO) { | |
692 // The slow branch is never taken. No need to build this guard. | |
693 return NULL; | |
694 } | |
695 | |
696 IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN); | |
697 | |
698 Node* if_slow = _gvn.transform( new (C, 1) IfTrueNode(iff) ); | |
699 if (if_slow == top()) { | |
700 // The slow branch is never taken. No need to build this guard. | |
701 return NULL; | |
702 } | |
703 | |
704 if (region != NULL) | |
705 region->add_req(if_slow); | |
706 | |
707 Node* if_fast = _gvn.transform( new (C, 1) IfFalseNode(iff) ); | |
708 set_control(if_fast); | |
709 | |
710 return if_slow; | |
711 } | |
712 | |
713 inline Node* LibraryCallKit::generate_slow_guard(Node* test, RegionNode* region) { | |
714 return generate_guard(test, region, PROB_UNLIKELY_MAG(3)); | |
715 } | |
716 inline Node* LibraryCallKit::generate_fair_guard(Node* test, RegionNode* region) { | |
717 return generate_guard(test, region, PROB_FAIR); | |
718 } | |
719 | |
720 inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* region, | |
721 Node* *pos_index) { | |
722 if (stopped()) | |
723 return NULL; // already stopped | |
724 if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint] | |
725 return NULL; // index is already adequately typed | |
726 Node* cmp_lt = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) ); | |
727 Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) ); | |
728 Node* is_neg = generate_guard(bol_lt, region, PROB_MIN); | |
729 if (is_neg != NULL && pos_index != NULL) { | |
730 // Emulate effect of Parse::adjust_map_after_if. | |
731 Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS); | |
732 ccast->set_req(0, control()); | |
733 (*pos_index) = _gvn.transform(ccast); | |
734 } | |
735 return is_neg; | |
736 } | |
737 | |
738 inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_negative, | |
739 Node* *pos_index) { | |
740 if (stopped()) | |
741 return NULL; // already stopped | |
742 if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint] | |
743 return NULL; // index is already adequately typed | |
744 Node* cmp_le = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) ); | |
745 BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le); | |
746 Node* bol_le = _gvn.transform( new (C, 2) BoolNode(cmp_le, le_or_eq) ); | |
747 Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN); | |
748 if (is_notp != NULL && pos_index != NULL) { | |
749 // Emulate effect of Parse::adjust_map_after_if. | |
750 Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS1); | |
751 ccast->set_req(0, control()); | |
752 (*pos_index) = _gvn.transform(ccast); | |
753 } | |
754 return is_notp; | |
755 } | |
756 | |
757 // Make sure that 'position' is a valid limit index, in [0..length]. | |
758 // There are two equivalent plans for checking this: | |
759 // A. (offset + copyLength) unsigned<= arrayLength | |
760 // B. offset <= (arrayLength - copyLength) | |
761 // We require that all of the values above, except for the sum and | |
762 // difference, are already known to be non-negative. | |
763 // Plan A is robust in the face of overflow, if offset and copyLength | |
764 // are both hugely positive. | |
765 // | |
766 // Plan B is less direct and intuitive, but it does not overflow at | |
767 // all, since the difference of two non-negatives is always | |
768 // representable. Whenever Java methods must perform the equivalent | |
769 // check they generally use Plan B instead of Plan A. | |
770 // For the moment we use Plan A. | |
771 inline Node* LibraryCallKit::generate_limit_guard(Node* offset, | |
772 Node* subseq_length, | |
773 Node* array_length, | |
774 RegionNode* region) { | |
775 if (stopped()) | |
776 return NULL; // already stopped | |
777 bool zero_offset = _gvn.type(offset) == TypeInt::ZERO; | |
778 if (zero_offset && _gvn.eqv_uncast(subseq_length, array_length)) | |
779 return NULL; // common case of whole-array copy | |
780 Node* last = subseq_length; | |
781 if (!zero_offset) // last += offset | |
782 last = _gvn.transform( new (C, 3) AddINode(last, offset)); | |
783 Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) ); | |
784 Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) ); | |
785 Node* is_over = generate_guard(bol_lt, region, PROB_MIN); | |
786 return is_over; | |
787 } | |
788 | |
789 | |
790 //--------------------------generate_current_thread-------------------- | |
791 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) { | |
792 ciKlass* thread_klass = env()->Thread_klass(); | |
793 const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull); | |
794 Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode()); | |
795 Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset())); | |
796 Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT); | |
797 tls_output = thread; | |
798 return threadObj; | |
799 } | |
800 | |
801 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
802 //------------------------------make_string_method_node------------------------ |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
803 // Helper method for String intrinsic finctions. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
804 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
805 const int value_offset = java_lang_String::value_offset_in_bytes(); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
806 const int count_offset = java_lang_String::count_offset_in_bytes(); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
807 const int offset_offset = java_lang_String::offset_offset_in_bytes(); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
808 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
809 Node* no_ctrl = NULL; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
810 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
811 ciInstanceKlass* klass = env()->String_klass(); |
1496
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
812 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
813 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
814 const TypeAryPtr* value_type = |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
815 TypeAryPtr::make(TypePtr::NotNull, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
816 TypeAry::make(TypeInt::CHAR,TypeInt::POS), |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
817 ciTypeArrayKlass::make(T_CHAR), true, 0); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
818 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
819 // Get start addr of string and substring |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
820 Node* str1_valuea = basic_plus_adr(str1, str1, value_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
821 Node* str1_value = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
822 Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
823 Node* str1_offset = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
824 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
|
825 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
826 // Pin loads from String::equals() argument since it could be NULL. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
827 Node* str2_ctrl = (opcode == Op_StrEquals) ? control() : no_ctrl; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
828 Node* str2_valuea = basic_plus_adr(str2, str2, value_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
829 Node* str2_value = make_load(str2_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
830 Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
831 Node* str2_offset = make_load(str2_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
832 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
|
833 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
834 Node* result = NULL; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
835 switch (opcode) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
836 case Op_StrIndexOf: |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
837 result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
838 str1_start, cnt1, str2_start, cnt2); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
839 break; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
840 case Op_StrComp: |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
841 result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS), |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
842 str1_start, cnt1, str2_start, cnt2); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
843 break; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
844 case Op_StrEquals: |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
845 result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
846 str1_start, str2_start, cnt1); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
847 break; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
848 default: |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
849 ShouldNotReachHere(); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
850 return NULL; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
851 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
852 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
853 // All these intrinsics have checks. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
854 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
|
855 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
856 return _gvn.transform(result); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
857 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
858 |
0 | 859 //------------------------------inline_string_compareTo------------------------ |
860 bool LibraryCallKit::inline_string_compareTo() { | |
861 | |
681 | 862 if (!Matcher::has_match_rule(Op_StrComp)) return false; |
863 | |
0 | 864 const int value_offset = java_lang_String::value_offset_in_bytes(); |
865 const int count_offset = java_lang_String::count_offset_in_bytes(); | |
866 const int offset_offset = java_lang_String::offset_offset_in_bytes(); | |
867 | |
868 _sp += 2; | |
869 Node *argument = pop(); // pop non-receiver first: it was pushed second | |
870 Node *receiver = pop(); | |
871 | |
872 // Null check on self without removing any arguments. The argument | |
873 // null check technically happens in the wrong place, which can lead to | |
874 // invalid stack traces when string compare is inlined into a method | |
875 // which handles NullPointerExceptions. | |
876 _sp += 2; | |
877 receiver = do_null_check(receiver, T_OBJECT); | |
878 argument = do_null_check(argument, T_OBJECT); | |
879 _sp -= 2; | |
880 if (stopped()) { | |
881 return true; | |
882 } | |
883 | |
884 ciInstanceKlass* klass = env()->String_klass(); | |
1496
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
885 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
886 Node* no_ctrl = NULL; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
887 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
888 // Get counts for string and argument |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
889 Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
890 Node* receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
891 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
892 Node* argument_cnta = basic_plus_adr(argument, argument, count_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
893 Node* argument_cnt = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
894 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
895 Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt); |
0 | 896 push(compare); |
897 return true; | |
898 } | |
899 | |
681 | 900 //------------------------------inline_string_equals------------------------ |
901 bool LibraryCallKit::inline_string_equals() { | |
902 | |
903 if (!Matcher::has_match_rule(Op_StrEquals)) return false; | |
904 | |
905 const int value_offset = java_lang_String::value_offset_in_bytes(); | |
906 const int count_offset = java_lang_String::count_offset_in_bytes(); | |
907 const int offset_offset = java_lang_String::offset_offset_in_bytes(); | |
908 | |
909 _sp += 2; | |
910 Node* argument = pop(); // pop non-receiver first: it was pushed second | |
911 Node* receiver = pop(); | |
912 | |
913 // Null check on self without removing any arguments. The argument | |
914 // null check technically happens in the wrong place, which can lead to | |
915 // invalid stack traces when string compare is inlined into a method | |
916 // which handles NullPointerExceptions. | |
917 _sp += 2; | |
918 receiver = do_null_check(receiver, T_OBJECT); | |
919 //should not do null check for argument for String.equals(), because spec | |
920 //allows to specify NULL as argument. | |
921 _sp -= 2; | |
922 | |
923 if (stopped()) { | |
924 return true; | |
925 } | |
926 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
927 // paths (plus control) merge |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
928 RegionNode* region = new (C, 5) RegionNode(5); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
929 Node* phi = new (C, 5) PhiNode(region, TypeInt::BOOL); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
930 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
931 // does source == target string? |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
932 Node* cmp = _gvn.transform(new (C, 3) CmpPNode(receiver, argument)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
933 Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
934 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
935 Node* if_eq = generate_slow_guard(bol, NULL); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
936 if (if_eq != NULL) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
937 // receiver == argument |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
938 phi->init_req(2, intcon(1)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
939 region->init_req(2, if_eq); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
940 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
941 |
681 | 942 // get String klass for instanceOf |
943 ciInstanceKlass* klass = env()->String_klass(); | |
944 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
945 if (!stopped()) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
946 Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass))); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
947 Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1))); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
948 Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
949 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
950 Node* inst_false = generate_guard(bol, NULL, PROB_MIN); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
951 //instanceOf == true, fallthrough |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
952 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
953 if (inst_false != NULL) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
954 phi->init_req(3, intcon(0)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
955 region->init_req(3, inst_false); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
956 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
957 } |
681 | 958 |
1496
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
959 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
681 | 960 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
961 Node* no_ctrl = NULL; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
962 Node* receiver_cnt; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
963 Node* argument_cnt; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
964 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
965 if (!stopped()) { |
1496
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
966 // Properly cast the argument to String |
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
967 argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type)); |
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
968 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
969 // Get counts for string and argument |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
970 Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
971 receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
972 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
973 // Pin load from argument string since it could be NULL. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
974 Node* argument_cnta = basic_plus_adr(argument, argument, count_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
975 argument_cnt = make_load(control(), argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
976 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
977 // Check for receiver count != argument count |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
978 Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) ); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
979 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) ); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
980 Node* if_ne = generate_slow_guard(bol, NULL); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
981 if (if_ne != NULL) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
982 phi->init_req(4, intcon(0)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
983 region->init_req(4, if_ne); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
984 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
985 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
986 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
987 // Check for count == 0 is done by mach node StrEquals. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
988 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
989 if (!stopped()) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
990 Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
991 phi->init_req(1, equals); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
992 region->init_req(1, control()); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
993 } |
681 | 994 |
995 // post merge | |
996 set_control(_gvn.transform(region)); | |
997 record_for_igvn(region); | |
998 | |
999 push(_gvn.transform(phi)); | |
1000 | |
1001 return true; | |
1002 } | |
1003 | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1004 //------------------------------inline_array_equals---------------------------- |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1005 bool LibraryCallKit::inline_array_equals() { |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1006 |
174
510f98a80563
6709972: runThese failed with assert(false,"bad AD file")
rasbold
parents:
169
diff
changeset
|
1007 if (!Matcher::has_match_rule(Op_AryEq)) return false; |
510f98a80563
6709972: runThese failed with assert(false,"bad AD file")
rasbold
parents:
169
diff
changeset
|
1008 |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1009 _sp += 2; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1010 Node *argument2 = pop(); |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1011 Node *argument1 = pop(); |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1012 |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1013 Node* equals = |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1014 _gvn.transform(new (C, 4) AryEqNode(control(), memory(TypeAryPtr::CHARS), |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1015 argument1, argument2) ); |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1016 push(equals); |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1017 return true; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1018 } |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
1019 |
0 | 1020 // Java version of String.indexOf(constant string) |
1021 // class StringDecl { | |
1022 // StringDecl(char[] ca) { | |
1023 // offset = 0; | |
1024 // count = ca.length; | |
1025 // value = ca; | |
1026 // } | |
1027 // int offset; | |
1028 // int count; | |
1029 // char[] value; | |
1030 // } | |
1031 // | |
1032 // static int string_indexOf_J(StringDecl string_object, char[] target_object, | |
1033 // int targetOffset, int cache_i, int md2) { | |
1034 // int cache = cache_i; | |
1035 // int sourceOffset = string_object.offset; | |
1036 // int sourceCount = string_object.count; | |
1037 // int targetCount = target_object.length; | |
1038 // | |
1039 // int targetCountLess1 = targetCount - 1; | |
1040 // int sourceEnd = sourceOffset + sourceCount - targetCountLess1; | |
1041 // | |
1042 // char[] source = string_object.value; | |
1043 // char[] target = target_object; | |
1044 // int lastChar = target[targetCountLess1]; | |
1045 // | |
1046 // outer_loop: | |
1047 // for (int i = sourceOffset; i < sourceEnd; ) { | |
1048 // int src = source[i + targetCountLess1]; | |
1049 // if (src == lastChar) { | |
1050 // // With random strings and a 4-character alphabet, | |
1051 // // reverse matching at this point sets up 0.8% fewer | |
1052 // // frames, but (paradoxically) makes 0.3% more probes. | |
1053 // // Since those probes are nearer the lastChar probe, | |
1054 // // there is may be a net D$ win with reverse matching. | |
1055 // // But, reversing loop inhibits unroll of inner loop | |
1056 // // for unknown reason. So, does running outer loop from | |
1057 // // (sourceOffset - targetCountLess1) to (sourceOffset + sourceCount) | |
1058 // for (int j = 0; j < targetCountLess1; j++) { | |
1059 // if (target[targetOffset + j] != source[i+j]) { | |
1060 // if ((cache & (1 << source[i+j])) == 0) { | |
1061 // if (md2 < j+1) { | |
1062 // i += j+1; | |
1063 // continue outer_loop; | |
1064 // } | |
1065 // } | |
1066 // i += md2; | |
1067 // continue outer_loop; | |
1068 // } | |
1069 // } | |
1070 // return i - sourceOffset; | |
1071 // } | |
1072 // if ((cache & (1 << src)) == 0) { | |
1073 // i += targetCountLess1; | |
1074 // } // using "i += targetCount;" and an "else i++;" causes a jump to jump. | |
1075 // i++; | |
1076 // } | |
1077 // return -1; | |
1078 // } | |
1079 | |
1080 //------------------------------string_indexOf------------------------ | |
1081 Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_array, jint targetOffset_i, | |
1082 jint cache_i, jint md2_i) { | |
1083 | |
1084 Node* no_ctrl = NULL; | |
1085 float likely = PROB_LIKELY(0.9); | |
1086 float unlikely = PROB_UNLIKELY(0.9); | |
1087 | |
1088 const int value_offset = java_lang_String::value_offset_in_bytes(); | |
1089 const int count_offset = java_lang_String::count_offset_in_bytes(); | |
1090 const int offset_offset = java_lang_String::offset_offset_in_bytes(); | |
1091 | |
1092 ciInstanceKlass* klass = env()->String_klass(); | |
1496
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
1093 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
0 | 1094 const TypeAryPtr* source_type = TypeAryPtr::make(TypePtr::NotNull, TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0); |
1095 | |
1096 Node* sourceOffseta = basic_plus_adr(string_object, string_object, offset_offset); | |
1097 Node* sourceOffset = make_load(no_ctrl, sourceOffseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset)); | |
1098 Node* sourceCounta = basic_plus_adr(string_object, string_object, count_offset); | |
1099 Node* sourceCount = make_load(no_ctrl, sourceCounta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); | |
1100 Node* sourcea = basic_plus_adr(string_object, string_object, value_offset); | |
1101 Node* source = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset)); | |
1102 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1103 Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array)) ); |
0 | 1104 jint target_length = target_array->length(); |
1105 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); | |
1106 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); | |
1107 | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
1108 IdealKit kit(gvn(), control(), merged_memory(), false, true); |
0 | 1109 #define __ kit. |
1110 Node* zero = __ ConI(0); | |
1111 Node* one = __ ConI(1); | |
1112 Node* cache = __ ConI(cache_i); | |
1113 Node* md2 = __ ConI(md2_i); | |
1114 Node* lastChar = __ ConI(target_array->char_at(target_length - 1)); | |
1115 Node* targetCount = __ ConI(target_length); | |
1116 Node* targetCountLess1 = __ ConI(target_length - 1); | |
1117 Node* targetOffset = __ ConI(targetOffset_i); | |
1118 Node* sourceEnd = __ SubI(__ AddI(sourceOffset, sourceCount), targetCountLess1); | |
1119 | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
1120 IdealVariable rtn(kit), i(kit), j(kit); __ declarations_done(); |
0 | 1121 Node* outer_loop = __ make_label(2 /* goto */); |
1122 Node* return_ = __ make_label(1); | |
1123 | |
1124 __ set(rtn,__ ConI(-1)); | |
1125 __ loop(i, sourceOffset, BoolTest::lt, sourceEnd); { | |
1126 Node* i2 = __ AddI(__ value(i), targetCountLess1); | |
1127 // pin to prohibit loading of "next iteration" value which may SEGV (rare) | |
1128 Node* src = load_array_element(__ ctrl(), source, i2, TypeAryPtr::CHARS); | |
1129 __ if_then(src, BoolTest::eq, lastChar, unlikely); { | |
1130 __ loop(j, zero, BoolTest::lt, targetCountLess1); { | |
1131 Node* tpj = __ AddI(targetOffset, __ value(j)); | |
1132 Node* targ = load_array_element(no_ctrl, target, tpj, target_type); | |
1133 Node* ipj = __ AddI(__ value(i), __ value(j)); | |
1134 Node* src2 = load_array_element(no_ctrl, source, ipj, TypeAryPtr::CHARS); | |
1135 __ if_then(targ, BoolTest::ne, src2); { | |
1136 __ if_then(__ AndI(cache, __ LShiftI(one, src2)), BoolTest::eq, zero); { | |
1137 __ if_then(md2, BoolTest::lt, __ AddI(__ value(j), one)); { | |
1138 __ increment(i, __ AddI(__ value(j), one)); | |
1139 __ goto_(outer_loop); | |
1140 } __ end_if(); __ dead(j); | |
1141 }__ end_if(); __ dead(j); | |
1142 __ increment(i, md2); | |
1143 __ goto_(outer_loop); | |
1144 }__ end_if(); | |
1145 __ increment(j, one); | |
1146 }__ end_loop(); __ dead(j); | |
1147 __ set(rtn, __ SubI(__ value(i), sourceOffset)); __ dead(i); | |
1148 __ goto_(return_); | |
1149 }__ end_if(); | |
1150 __ if_then(__ AndI(cache, __ LShiftI(one, src)), BoolTest::eq, zero, likely); { | |
1151 __ increment(i, targetCountLess1); | |
1152 }__ end_if(); | |
1153 __ increment(i, one); | |
1154 __ bind(outer_loop); | |
1155 }__ end_loop(); __ dead(i); | |
1156 __ bind(return_); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
1157 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
1158 // Final sync IdealKit and GraphKit. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
1159 sync_kit(kit); |
0 | 1160 Node* result = __ value(rtn); |
1161 #undef __ | |
1162 C->set_has_loops(true); | |
1163 return result; | |
1164 } | |
1165 | |
1166 //------------------------------inline_string_indexOf------------------------ | |
1167 bool LibraryCallKit::inline_string_indexOf() { | |
1168 | |
1169 const int value_offset = java_lang_String::value_offset_in_bytes(); | |
1170 const int count_offset = java_lang_String::count_offset_in_bytes(); | |
1171 const int offset_offset = java_lang_String::offset_offset_in_bytes(); | |
1172 | |
1173 _sp += 2; | |
681 | 1174 Node *argument = pop(); // pop non-receiver first: it was pushed second |
1175 Node *receiver = pop(); | |
1176 | |
1177 Node* result; | |
1504
ae8f909e5fc7
6948602: Disable use of SSE4.2 in String.indexOf intrinsic until 6942326 is fixed
iveresov
parents:
1396
diff
changeset
|
1178 // 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
|
1179 // the load doesn't cross into the uncommited space. |
ae8f909e5fc7
6948602: Disable use of SSE4.2 in String.indexOf intrinsic until 6942326 is fixed
iveresov
parents:
1396
diff
changeset
|
1180 if (false && Matcher::has_match_rule(Op_StrIndexOf) && |
681 | 1181 UseSSE42Intrinsics) { |
1182 // Generate SSE4.2 version of indexOf | |
1183 // We currently only have match rules that use SSE4.2 | |
1184 | |
1185 // Null check on self without removing any arguments. The argument | |
1186 // null check technically happens in the wrong place, which can lead to | |
1187 // invalid stack traces when string compare is inlined into a method | |
1188 // which handles NullPointerExceptions. | |
1189 _sp += 2; | |
1190 receiver = do_null_check(receiver, T_OBJECT); | |
1191 argument = do_null_check(argument, T_OBJECT); | |
1192 _sp -= 2; | |
1193 | |
1194 if (stopped()) { | |
1195 return true; | |
1196 } | |
1197 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1198 // Make the merge point |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1199 RegionNode* result_rgn = new (C, 3) RegionNode(3); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1200 Node* result_phi = new (C, 3) PhiNode(result_rgn, TypeInt::INT); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1201 Node* no_ctrl = NULL; |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1202 |
681 | 1203 ciInstanceKlass* klass = env()->String_klass(); |
1496
e8e83be27dd7
6951190: assert(!klass_is_exact(),"only non-exact klass") while building JDK
never
parents:
1396
diff
changeset
|
1204 const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); |
681 | 1205 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1206 // Get counts for string and substr |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1207 Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1208 Node* source_cnt = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1209 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1210 Node* substr_cnta = basic_plus_adr(argument, argument, count_offset); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1211 Node* substr_cnt = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1212 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1213 // Check for substr count > string count |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1214 Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) ); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1215 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) ); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1216 Node* if_gt = generate_slow_guard(bol, NULL); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1217 if (if_gt != NULL) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1218 result_phi->init_req(2, intcon(-1)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1219 result_rgn->init_req(2, if_gt); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1220 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1221 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1222 if (!stopped()) { |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1223 result = make_string_method_node(Op_StrIndexOf, receiver, source_cnt, argument, substr_cnt); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1224 result_phi->init_req(1, result); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1225 result_rgn->init_req(1, control()); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1226 } |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1227 set_control(_gvn.transform(result_rgn)); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1228 record_for_igvn(result_rgn); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1229 result = _gvn.transform(result_phi); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
958
diff
changeset
|
1230 |
681 | 1231 } else { //Use LibraryCallKit::string_indexOf |
1232 // don't intrinsify is argument isn't a constant string. | |
1233 if (!argument->is_Con()) { | |
1234 return false; | |
1235 } | |
1236 const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr(); | |
1237 if (str_type == NULL) { | |
1238 return false; | |
1239 } | |
1240 ciInstanceKlass* klass = env()->String_klass(); | |
1241 ciObject* str_const = str_type->const_oop(); | |
1242 if (str_const == NULL || str_const->klass() != klass) { | |
1243 return false; | |
1244 } | |
1245 ciInstance* str = str_const->as_instance(); | |
1246 assert(str != NULL, "must be instance"); | |
1247 | |
1248 ciObject* v = str->field_value_by_offset(value_offset).as_object(); | |
1249 int o = str->field_value_by_offset(offset_offset).as_int(); | |
1250 int c = str->field_value_by_offset(count_offset).as_int(); | |
1251 ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array | |
1252 | |
1253 // constant strings have no offset and count == length which | |
1254 // simplifies the resulting code somewhat so lets optimize for that. | |
1255 if (o != 0 || c != pat->length()) { | |
1256 return false; | |
1257 } | |
1258 | |
1259 // Null check on self without removing any arguments. The argument | |
1260 // null check technically happens in the wrong place, which can lead to | |
1261 // invalid stack traces when string compare is inlined into a method | |
1262 // which handles NullPointerExceptions. | |
1263 _sp += 2; | |
1264 receiver = do_null_check(receiver, T_OBJECT); | |
1265 // No null check on the argument is needed since it's a constant String oop. | |
1266 _sp -= 2; | |
1267 if (stopped()) { | |
1268 return true; | |
1269 } | |
1270 | |
1271 // The null string as a pattern always returns 0 (match at beginning of string) | |
1272 if (c == 0) { | |
1273 push(intcon(0)); | |
1274 return true; | |
1275 } | |
1276 | |
1277 // Generate default indexOf | |
1278 jchar lastChar = pat->char_at(o + (c - 1)); | |
1279 int cache = 0; | |
1280 int i; | |
1281 for (i = 0; i < c - 1; i++) { | |
1282 assert(i < pat->length(), "out of range"); | |
1283 cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1))); | |
1284 } | |
1285 | |
1286 int md2 = c; | |
1287 for (i = 0; i < c - 1; i++) { | |
1288 assert(i < pat->length(), "out of range"); | |
1289 if (pat->char_at(o + i) == lastChar) { | |
1290 md2 = (c - 1) - i; | |
1291 } | |
1292 } | |
1293 | |
1294 result = string_indexOf(receiver, pat, o, cache, md2); | |
0 | 1295 } |
1296 | |
1297 push(result); | |
1298 return true; | |
1299 } | |
1300 | |
1301 //--------------------------pop_math_arg-------------------------------- | |
1302 // Pop a double argument to a math function from the stack | |
1303 // rounding it if necessary. | |
1304 Node * LibraryCallKit::pop_math_arg() { | |
1305 Node *arg = pop_pair(); | |
1306 if( Matcher::strict_fp_requires_explicit_rounding && UseSSE<=1 ) | |
1307 arg = _gvn.transform( new (C, 2) RoundDoubleNode(0, arg) ); | |
1308 return arg; | |
1309 } | |
1310 | |
1311 //------------------------------inline_trig---------------------------------- | |
1312 // Inline sin/cos/tan instructions, if possible. If rounding is required, do | |
1313 // argument reduction which will turn into a fast/slow diamond. | |
1314 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) { | |
1315 _sp += arg_size(); // restore stack pointer | |
1316 Node* arg = pop_math_arg(); | |
1317 Node* trig = NULL; | |
1318 | |
1319 switch (id) { | |
1320 case vmIntrinsics::_dsin: | |
1321 trig = _gvn.transform((Node*)new (C, 2) SinDNode(arg)); | |
1322 break; | |
1323 case vmIntrinsics::_dcos: | |
1324 trig = _gvn.transform((Node*)new (C, 2) CosDNode(arg)); | |
1325 break; | |
1326 case vmIntrinsics::_dtan: | |
1327 trig = _gvn.transform((Node*)new (C, 2) TanDNode(arg)); | |
1328 break; | |
1329 default: | |
1330 assert(false, "bad intrinsic was passed in"); | |
1331 return false; | |
1332 } | |
1333 | |
1334 // Rounding required? Check for argument reduction! | |
1335 if( Matcher::strict_fp_requires_explicit_rounding ) { | |
1336 | |
1337 static const double pi_4 = 0.7853981633974483; | |
1338 static const double neg_pi_4 = -0.7853981633974483; | |
1339 // pi/2 in 80-bit extended precision | |
1340 // static const unsigned char pi_2_bits_x[] = {0x35,0xc2,0x68,0x21,0xa2,0xda,0x0f,0xc9,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00}; | |
1341 // -pi/2 in 80-bit extended precision | |
1342 // 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}; | |
1343 // Cutoff value for using this argument reduction technique | |
1344 //static const double pi_2_minus_epsilon = 1.564660403643354; | |
1345 //static const double neg_pi_2_plus_epsilon = -1.564660403643354; | |
1346 | |
1347 // Pseudocode for sin: | |
1348 // if (x <= Math.PI / 4.0) { | |
1349 // if (x >= -Math.PI / 4.0) return fsin(x); | |
1350 // if (x >= -Math.PI / 2.0) return -fcos(x + Math.PI / 2.0); | |
1351 // } else { | |
1352 // if (x <= Math.PI / 2.0) return fcos(x - Math.PI / 2.0); | |
1353 // } | |
1354 // return StrictMath.sin(x); | |
1355 | |
1356 // Pseudocode for cos: | |
1357 // if (x <= Math.PI / 4.0) { | |
1358 // if (x >= -Math.PI / 4.0) return fcos(x); | |
1359 // if (x >= -Math.PI / 2.0) return fsin(x + Math.PI / 2.0); | |
1360 // } else { | |
1361 // if (x <= Math.PI / 2.0) return -fsin(x - Math.PI / 2.0); | |
1362 // } | |
1363 // return StrictMath.cos(x); | |
1364 | |
1365 // Actually, sticking in an 80-bit Intel value into C2 will be tough; it | |
1366 // requires a special machine instruction to load it. Instead we'll try | |
1367 // the 'easy' case. If we really need the extra range +/- PI/2 we'll | |
1368 // probably do the math inside the SIN encoding. | |
1369 | |
1370 // Make the merge point | |
1371 RegionNode *r = new (C, 3) RegionNode(3); | |
1372 Node *phi = new (C, 3) PhiNode(r,Type::DOUBLE); | |
1373 | |
1374 // Flatten arg so we need only 1 test | |
1375 Node *abs = _gvn.transform(new (C, 2) AbsDNode(arg)); | |
1376 // Node for PI/4 constant | |
1377 Node *pi4 = makecon(TypeD::make(pi_4)); | |
1378 // Check PI/4 : abs(arg) | |
1379 Node *cmp = _gvn.transform(new (C, 3) CmpDNode(pi4,abs)); | |
1380 // Check: If PI/4 < abs(arg) then go slow | |
1381 Node *bol = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::lt ) ); | |
1382 // Branch either way | |
1383 IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); | |
1384 set_control(opt_iff(r,iff)); | |
1385 | |
1386 // Set fast path result | |
1387 phi->init_req(2,trig); | |
1388 | |
1389 // Slow path - non-blocking leaf call | |
1390 Node* call = NULL; | |
1391 switch (id) { | |
1392 case vmIntrinsics::_dsin: | |
1393 call = make_runtime_call(RC_LEAF, OptoRuntime::Math_D_D_Type(), | |
1394 CAST_FROM_FN_PTR(address, SharedRuntime::dsin), | |
1395 "Sin", NULL, arg, top()); | |
1396 break; | |
1397 case vmIntrinsics::_dcos: | |
1398 call = make_runtime_call(RC_LEAF, OptoRuntime::Math_D_D_Type(), | |
1399 CAST_FROM_FN_PTR(address, SharedRuntime::dcos), | |
1400 "Cos", NULL, arg, top()); | |
1401 break; | |
1402 case vmIntrinsics::_dtan: | |
1403 call = make_runtime_call(RC_LEAF, OptoRuntime::Math_D_D_Type(), | |
1404 CAST_FROM_FN_PTR(address, SharedRuntime::dtan), | |
1405 "Tan", NULL, arg, top()); | |
1406 break; | |
1407 } | |
1408 assert(control()->in(0) == call, ""); | |
1409 Node* slow_result = _gvn.transform(new (C, 1) ProjNode(call,TypeFunc::Parms)); | |
1410 r->init_req(1,control()); | |
1411 phi->init_req(1,slow_result); | |
1412 | |
1413 // Post-merge | |
1414 set_control(_gvn.transform(r)); | |
1415 record_for_igvn(r); | |
1416 trig = _gvn.transform(phi); | |
1417 | |
1418 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
1419 } | |
1420 // Push result back on JVM stack | |
1421 push_pair(trig); | |
1422 return true; | |
1423 } | |
1424 | |
1425 //------------------------------inline_sqrt------------------------------------- | |
1426 // Inline square root instruction, if possible. | |
1427 bool LibraryCallKit::inline_sqrt(vmIntrinsics::ID id) { | |
1428 assert(id == vmIntrinsics::_dsqrt, "Not square root"); | |
1429 _sp += arg_size(); // restore stack pointer | |
1430 push_pair(_gvn.transform(new (C, 2) SqrtDNode(0, pop_math_arg()))); | |
1431 return true; | |
1432 } | |
1433 | |
1434 //------------------------------inline_abs------------------------------------- | |
1435 // Inline absolute value instruction, if possible. | |
1436 bool LibraryCallKit::inline_abs(vmIntrinsics::ID id) { | |
1437 assert(id == vmIntrinsics::_dabs, "Not absolute value"); | |
1438 _sp += arg_size(); // restore stack pointer | |
1439 push_pair(_gvn.transform(new (C, 2) AbsDNode(pop_math_arg()))); | |
1440 return true; | |
1441 } | |
1442 | |
1443 //------------------------------inline_exp------------------------------------- | |
1444 // Inline exp instructions, if possible. The Intel hardware only misses | |
1445 // really odd corner cases (+/- Infinity). Just uncommon-trap them. | |
1446 bool LibraryCallKit::inline_exp(vmIntrinsics::ID id) { | |
1447 assert(id == vmIntrinsics::_dexp, "Not exp"); | |
1448 | |
1449 // If this inlining ever returned NaN in the past, we do not intrinsify it | |
1450 // every again. NaN results requires StrictMath.exp handling. | |
1451 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; | |
1452 | |
1453 // Do not intrinsify on older platforms which lack cmove. | |
1454 if (ConditionalMoveLimit == 0) return false; | |
1455 | |
1456 _sp += arg_size(); // restore stack pointer | |
1457 Node *x = pop_math_arg(); | |
1458 Node *result = _gvn.transform(new (C, 2) ExpDNode(0,x)); | |
1459 | |
1460 //------------------- | |
1461 //result=(result.isNaN())? StrictMath::exp():result; | |
1462 // Check: If isNaN() by checking result!=result? then go to Strict Math | |
1463 Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result)); | |
1464 // Build the boolean node | |
1465 Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) ); | |
1466 | |
1467 { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT); | |
1468 // End the current control-flow path | |
1469 push_pair(x); | |
1470 // Math.exp intrinsic returned a NaN, which requires StrictMath.exp | |
1471 // to handle. Recompile without intrinsifying Math.exp | |
1472 uncommon_trap(Deoptimization::Reason_intrinsic, | |
1473 Deoptimization::Action_make_not_entrant); | |
1474 } | |
1475 | |
1476 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
1477 | |
1478 push_pair(result); | |
1479 | |
1480 return true; | |
1481 } | |
1482 | |
1483 //------------------------------inline_pow------------------------------------- | |
1484 // Inline power instructions, if possible. | |
1485 bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) { | |
1486 assert(id == vmIntrinsics::_dpow, "Not pow"); | |
1487 | |
1488 // If this inlining ever returned NaN in the past, we do not intrinsify it | |
1489 // every again. NaN results requires StrictMath.pow handling. | |
1490 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; | |
1491 | |
1492 // Do not intrinsify on older platforms which lack cmove. | |
1493 if (ConditionalMoveLimit == 0) return false; | |
1494 | |
1495 // Pseudocode for pow | |
1496 // if (x <= 0.0) { | |
1497 // if ((double)((int)y)==y) { // if y is int | |
1498 // result = ((1&(int)y)==0)?-DPow(abs(x), y):DPow(abs(x), y) | |
1499 // } else { | |
1500 // result = NaN; | |
1501 // } | |
1502 // } else { | |
1503 // result = DPow(x,y); | |
1504 // } | |
1505 // if (result != result)? { | |
605 | 1506 // uncommon_trap(); |
0 | 1507 // } |
1508 // return result; | |
1509 | |
1510 _sp += arg_size(); // restore stack pointer | |
1511 Node* y = pop_math_arg(); | |
1512 Node* x = pop_math_arg(); | |
1513 | |
1514 Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) ); | |
1515 | |
1516 // Short form: if not top-level (i.e., Math.pow but inlining Math.pow | |
1517 // inside of something) then skip the fancy tests and just check for | |
1518 // NaN result. | |
1519 Node *result = NULL; | |
1520 if( jvms()->depth() >= 1 ) { | |
1521 result = fast_result; | |
1522 } else { | |
1523 | |
1524 // Set the merge point for If node with condition of (x <= 0.0) | |
1525 // There are four possible paths to region node and phi node | |
1526 RegionNode *r = new (C, 4) RegionNode(4); | |
1527 Node *phi = new (C, 4) PhiNode(r, Type::DOUBLE); | |
1528 | |
1529 // Build the first if node: if (x <= 0.0) | |
1530 // Node for 0 constant | |
1531 Node *zeronode = makecon(TypeD::ZERO); | |
1532 // Check x:0 | |
1533 Node *cmp = _gvn.transform(new (C, 3) CmpDNode(x, zeronode)); | |
1534 // Check: If (x<=0) then go complex path | |
1535 Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::le ) ); | |
1536 // Branch either way | |
1537 IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); | |
1538 Node *opt_test = _gvn.transform(if1); | |
1539 //assert( opt_test->is_If(), "Expect an IfNode"); | |
1540 IfNode *opt_if1 = (IfNode*)opt_test; | |
1541 // Fast path taken; set region slot 3 | |
1542 Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_if1) ); | |
1543 r->init_req(3,fast_taken); // Capture fast-control | |
1544 | |
1545 // Fast path not-taken, i.e. slow path | |
1546 Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(opt_if1) ); | |
1547 | |
1548 // Set fast path result | |
1549 Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, y, x) ); | |
1550 phi->init_req(3, fast_result); | |
1551 | |
1552 // Complex path | |
1553 // Build the second if node (if y is int) | |
1554 // Node for (int)y | |
1555 Node *inty = _gvn.transform( new (C, 2) ConvD2INode(y)); | |
1556 // Node for (double)((int) y) | |
1557 Node *doubleinty= _gvn.transform( new (C, 2) ConvI2DNode(inty)); | |
1558 // Check (double)((int) y) : y | |
1559 Node *cmpinty= _gvn.transform(new (C, 3) CmpDNode(doubleinty, y)); | |
1560 // Check if (y isn't int) then go to slow path | |
1561 | |
1562 Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmpinty, BoolTest::ne ) ); | |
605 | 1563 // Branch either way |
0 | 1564 IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); |
1565 Node *slow_path = opt_iff(r,if2); // Set region path 2 | |
1566 | |
1567 // Calculate DPow(abs(x), y)*(1 & (int)y) | |
1568 // Node for constant 1 | |
1569 Node *conone = intcon(1); | |
1570 // 1& (int)y | |
1571 Node *signnode= _gvn.transform( new (C, 3) AndINode(conone, inty) ); | |
1572 // zero node | |
1573 Node *conzero = intcon(0); | |
1574 // Check (1&(int)y)==0? | |
1575 Node *cmpeq1 = _gvn.transform(new (C, 3) CmpINode(signnode, conzero)); | |
1576 // Check if (1&(int)y)!=0?, if so the result is negative | |
1577 Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmpeq1, BoolTest::ne ) ); | |
1578 // abs(x) | |
1579 Node *absx=_gvn.transform( new (C, 2) AbsDNode(x)); | |
1580 // abs(x)^y | |
1581 Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, y, absx) ); | |
1582 // -abs(x)^y | |
1583 Node *negabsxpowy = _gvn.transform(new (C, 2) NegDNode (absxpowy)); | |
1584 // (1&(int)y)==1?-DPow(abs(x), y):DPow(abs(x), y) | |
1585 Node *signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE)); | |
1586 // Set complex path fast result | |
1587 phi->init_req(2, signresult); | |
1588 | |
1589 static const jlong nan_bits = CONST64(0x7ff8000000000000); | |
1590 Node *slow_result = makecon(TypeD::make(*(double*)&nan_bits)); // return NaN | |
1591 r->init_req(1,slow_path); | |
1592 phi->init_req(1,slow_result); | |
1593 | |
1594 // Post merge | |
1595 set_control(_gvn.transform(r)); | |
1596 record_for_igvn(r); | |
1597 result=_gvn.transform(phi); | |
1598 } | |
1599 | |
1600 //------------------- | |
1601 //result=(result.isNaN())? uncommon_trap():result; | |
1602 // Check: If isNaN() by checking result!=result? then go to Strict Math | |
1603 Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result)); | |
1604 // Build the boolean node | |
1605 Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) ); | |
1606 | |
1607 { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT); | |
1608 // End the current control-flow path | |
1609 push_pair(x); | |
1610 push_pair(y); | |
1611 // Math.pow intrinsic returned a NaN, which requires StrictMath.pow | |
1612 // to handle. Recompile without intrinsifying Math.pow. | |
1613 uncommon_trap(Deoptimization::Reason_intrinsic, | |
1614 Deoptimization::Action_make_not_entrant); | |
1615 } | |
1616 | |
1617 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
1618 | |
1619 push_pair(result); | |
1620 | |
1621 return true; | |
1622 } | |
1623 | |
1624 //------------------------------inline_trans------------------------------------- | |
1625 // Inline transcendental instructions, if possible. The Intel hardware gets | |
1626 // these right, no funny corner cases missed. | |
1627 bool LibraryCallKit::inline_trans(vmIntrinsics::ID id) { | |
1628 _sp += arg_size(); // restore stack pointer | |
1629 Node* arg = pop_math_arg(); | |
1630 Node* trans = NULL; | |
1631 | |
1632 switch (id) { | |
1633 case vmIntrinsics::_dlog: | |
1634 trans = _gvn.transform((Node*)new (C, 2) LogDNode(arg)); | |
1635 break; | |
1636 case vmIntrinsics::_dlog10: | |
1637 trans = _gvn.transform((Node*)new (C, 2) Log10DNode(arg)); | |
1638 break; | |
1639 default: | |
1640 assert(false, "bad intrinsic was passed in"); | |
1641 return false; | |
1642 } | |
1643 | |
1644 // Push result back on JVM stack | |
1645 push_pair(trans); | |
1646 return true; | |
1647 } | |
1648 | |
1649 //------------------------------runtime_math----------------------------- | |
1650 bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) { | |
1651 Node* a = NULL; | |
1652 Node* b = NULL; | |
1653 | |
1654 assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(), | |
1655 "must be (DD)D or (D)D type"); | |
1656 | |
1657 // Inputs | |
1658 _sp += arg_size(); // restore stack pointer | |
1659 if (call_type == OptoRuntime::Math_DD_D_Type()) { | |
1660 b = pop_math_arg(); | |
1661 } | |
1662 a = pop_math_arg(); | |
1663 | |
1664 const TypePtr* no_memory_effects = NULL; | |
1665 Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, | |
1666 no_memory_effects, | |
1667 a, top(), b, b ? top() : NULL); | |
1668 Node* value = _gvn.transform(new (C, 1) ProjNode(trig, TypeFunc::Parms+0)); | |
1669 #ifdef ASSERT | |
1670 Node* value_top = _gvn.transform(new (C, 1) ProjNode(trig, TypeFunc::Parms+1)); | |
1671 assert(value_top == top(), "second value must be top"); | |
1672 #endif | |
1673 | |
1674 push_pair(value); | |
1675 return true; | |
1676 } | |
1677 | |
1678 //------------------------------inline_math_native----------------------------- | |
1679 bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) { | |
1680 switch (id) { | |
1681 // These intrinsics are not properly supported on all hardware | |
1682 case vmIntrinsics::_dcos: return Matcher::has_match_rule(Op_CosD) ? inline_trig(id) : | |
1683 runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dcos), "COS"); | |
1684 case vmIntrinsics::_dsin: return Matcher::has_match_rule(Op_SinD) ? inline_trig(id) : | |
1685 runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dsin), "SIN"); | |
1686 case vmIntrinsics::_dtan: return Matcher::has_match_rule(Op_TanD) ? inline_trig(id) : | |
1687 runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dtan), "TAN"); | |
1688 | |
1689 case vmIntrinsics::_dlog: return Matcher::has_match_rule(Op_LogD) ? inline_trans(id) : | |
1690 runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dlog), "LOG"); | |
1691 case vmIntrinsics::_dlog10: return Matcher::has_match_rule(Op_Log10D) ? inline_trans(id) : | |
1692 runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), "LOG10"); | |
1693 | |
1694 // These intrinsics are supported on all hardware | |
1695 case vmIntrinsics::_dsqrt: return Matcher::has_match_rule(Op_SqrtD) ? inline_sqrt(id) : false; | |
1696 case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_abs(id) : false; | |
1697 | |
1698 // These intrinsics don't work on X86. The ad implementation doesn't | |
1699 // handle NaN's properly. Instead of returning infinity, the ad | |
1700 // implementation returns a NaN on overflow. See bug: 6304089 | |
1701 // Once the ad implementations are fixed, change the code below | |
1702 // to match the intrinsics above | |
1703 | |
1704 case vmIntrinsics::_dexp: return | |
1705 runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP"); | |
1706 case vmIntrinsics::_dpow: return | |
1707 runtime_math(OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW"); | |
1708 | |
1709 // These intrinsics are not yet correctly implemented | |
1710 case vmIntrinsics::_datan2: | |
1711 return false; | |
1712 | |
1713 default: | |
1714 ShouldNotReachHere(); | |
1715 return false; | |
1716 } | |
1717 } | |
1718 | |
1719 static bool is_simple_name(Node* n) { | |
1720 return (n->req() == 1 // constant | |
1721 || (n->is_Type() && n->as_Type()->type()->singleton()) | |
1722 || n->is_Proj() // parameter or return value | |
1723 || n->is_Phi() // local of some sort | |
1724 ); | |
1725 } | |
1726 | |
1727 //----------------------------inline_min_max----------------------------------- | |
1728 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { | |
1729 push(generate_min_max(id, argument(0), argument(1))); | |
1730 | |
1731 return true; | |
1732 } | |
1733 | |
1734 Node* | |
1735 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { | |
1736 // These are the candidate return value: | |
1737 Node* xvalue = x0; | |
1738 Node* yvalue = y0; | |
1739 | |
1740 if (xvalue == yvalue) { | |
1741 return xvalue; | |
1742 } | |
1743 | |
1744 bool want_max = (id == vmIntrinsics::_max); | |
1745 | |
1746 const TypeInt* txvalue = _gvn.type(xvalue)->isa_int(); | |
1747 const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int(); | |
1748 if (txvalue == NULL || tyvalue == NULL) return top(); | |
1749 // This is not really necessary, but it is consistent with a | |
1750 // hypothetical MaxINode::Value method: | |
1751 int widen = MAX2(txvalue->_widen, tyvalue->_widen); | |
1752 | |
1753 // %%% This folding logic should (ideally) be in a different place. | |
1754 // Some should be inside IfNode, and there to be a more reliable | |
1755 // transformation of ?: style patterns into cmoves. We also want | |
1756 // more powerful optimizations around cmove and min/max. | |
1757 | |
1758 // Try to find a dominating comparison of these guys. | |
1759 // It can simplify the index computation for Arrays.copyOf | |
1760 // and similar uses of System.arraycopy. | |
1761 // First, compute the normalized version of CmpI(x, y). | |
1762 int cmp_op = Op_CmpI; | |
1763 Node* xkey = xvalue; | |
1764 Node* ykey = yvalue; | |
1765 Node* ideal_cmpxy = _gvn.transform( new(C, 3) CmpINode(xkey, ykey) ); | |
1766 if (ideal_cmpxy->is_Cmp()) { | |
1767 // E.g., if we have CmpI(length - offset, count), | |
1768 // it might idealize to CmpI(length, count + offset) | |
1769 cmp_op = ideal_cmpxy->Opcode(); | |
1770 xkey = ideal_cmpxy->in(1); | |
1771 ykey = ideal_cmpxy->in(2); | |
1772 } | |
1773 | |
1774 // Start by locating any relevant comparisons. | |
1775 Node* start_from = (xkey->outcnt() < ykey->outcnt()) ? xkey : ykey; | |
1776 Node* cmpxy = NULL; | |
1777 Node* cmpyx = NULL; | |
1778 for (DUIterator_Fast kmax, k = start_from->fast_outs(kmax); k < kmax; k++) { | |
1779 Node* cmp = start_from->fast_out(k); | |
1780 if (cmp->outcnt() > 0 && // must have prior uses | |
1781 cmp->in(0) == NULL && // must be context-independent | |
1782 cmp->Opcode() == cmp_op) { // right kind of compare | |
1783 if (cmp->in(1) == xkey && cmp->in(2) == ykey) cmpxy = cmp; | |
1784 if (cmp->in(1) == ykey && cmp->in(2) == xkey) cmpyx = cmp; | |
1785 } | |
1786 } | |
1787 | |
1788 const int NCMPS = 2; | |
1789 Node* cmps[NCMPS] = { cmpxy, cmpyx }; | |
1790 int cmpn; | |
1791 for (cmpn = 0; cmpn < NCMPS; cmpn++) { | |
1792 if (cmps[cmpn] != NULL) break; // find a result | |
1793 } | |
1794 if (cmpn < NCMPS) { | |
1795 // Look for a dominating test that tells us the min and max. | |
1796 int depth = 0; // Limit search depth for speed | |
1797 Node* dom = control(); | |
1798 for (; dom != NULL; dom = IfNode::up_one_dom(dom, true)) { | |
1799 if (++depth >= 100) break; | |
1800 Node* ifproj = dom; | |
1801 if (!ifproj->is_Proj()) continue; | |
1802 Node* iff = ifproj->in(0); | |
1803 if (!iff->is_If()) continue; | |
1804 Node* bol = iff->in(1); | |
1805 if (!bol->is_Bool()) continue; | |
1806 Node* cmp = bol->in(1); | |
1807 if (cmp == NULL) continue; | |
1808 for (cmpn = 0; cmpn < NCMPS; cmpn++) | |
1809 if (cmps[cmpn] == cmp) break; | |
1810 if (cmpn == NCMPS) continue; | |
1811 BoolTest::mask btest = bol->as_Bool()->_test._test; | |
1812 if (ifproj->is_IfFalse()) btest = BoolTest(btest).negate(); | |
1813 if (cmp->in(1) == ykey) btest = BoolTest(btest).commute(); | |
1814 // At this point, we know that 'x btest y' is true. | |
1815 switch (btest) { | |
1816 case BoolTest::eq: | |
1817 // They are proven equal, so we can collapse the min/max. | |
1818 // Either value is the answer. Choose the simpler. | |
1819 if (is_simple_name(yvalue) && !is_simple_name(xvalue)) | |
1820 return yvalue; | |
1821 return xvalue; | |
1822 case BoolTest::lt: // x < y | |
1823 case BoolTest::le: // x <= y | |
1824 return (want_max ? yvalue : xvalue); | |
1825 case BoolTest::gt: // x > y | |
1826 case BoolTest::ge: // x >= y | |
1827 return (want_max ? xvalue : yvalue); | |
1828 } | |
1829 } | |
1830 } | |
1831 | |
1832 // We failed to find a dominating test. | |
1833 // Let's pick a test that might GVN with prior tests. | |
1834 Node* best_bol = NULL; | |
1835 BoolTest::mask best_btest = BoolTest::illegal; | |
1836 for (cmpn = 0; cmpn < NCMPS; cmpn++) { | |
1837 Node* cmp = cmps[cmpn]; | |
1838 if (cmp == NULL) continue; | |
1839 for (DUIterator_Fast jmax, j = cmp->fast_outs(jmax); j < jmax; j++) { | |
1840 Node* bol = cmp->fast_out(j); | |
1841 if (!bol->is_Bool()) continue; | |
1842 BoolTest::mask btest = bol->as_Bool()->_test._test; | |
1843 if (btest == BoolTest::eq || btest == BoolTest::ne) continue; | |
1844 if (cmp->in(1) == ykey) btest = BoolTest(btest).commute(); | |
1845 if (bol->outcnt() > (best_bol == NULL ? 0 : best_bol->outcnt())) { | |
1846 best_bol = bol->as_Bool(); | |
1847 best_btest = btest; | |
1848 } | |
1849 } | |
1850 } | |
1851 | |
1852 Node* answer_if_true = NULL; | |
1853 Node* answer_if_false = NULL; | |
1854 switch (best_btest) { | |
1855 default: | |
1856 if (cmpxy == NULL) | |
1857 cmpxy = ideal_cmpxy; | |
1858 best_bol = _gvn.transform( new(C, 2) BoolNode(cmpxy, BoolTest::lt) ); | |
1859 // and fall through: | |
1860 case BoolTest::lt: // x < y | |
1861 case BoolTest::le: // x <= y | |
1862 answer_if_true = (want_max ? yvalue : xvalue); | |
1863 answer_if_false = (want_max ? xvalue : yvalue); | |
1864 break; | |
1865 case BoolTest::gt: // x > y | |
1866 case BoolTest::ge: // x >= y | |
1867 answer_if_true = (want_max ? xvalue : yvalue); | |
1868 answer_if_false = (want_max ? yvalue : xvalue); | |
1869 break; | |
1870 } | |
1871 | |
1872 jint hi, lo; | |
1873 if (want_max) { | |
1874 // We can sharpen the minimum. | |
1875 hi = MAX2(txvalue->_hi, tyvalue->_hi); | |
1876 lo = MAX2(txvalue->_lo, tyvalue->_lo); | |
1877 } else { | |
1878 // We can sharpen the maximum. | |
1879 hi = MIN2(txvalue->_hi, tyvalue->_hi); | |
1880 lo = MIN2(txvalue->_lo, tyvalue->_lo); | |
1881 } | |
1882 | |
1883 // Use a flow-free graph structure, to avoid creating excess control edges | |
1884 // which could hinder other optimizations. | |
1885 // Since Math.min/max is often used with arraycopy, we want | |
1886 // tightly_coupled_allocation to be able to see beyond min/max expressions. | |
1887 Node* cmov = CMoveNode::make(C, NULL, best_bol, | |
1888 answer_if_false, answer_if_true, | |
1889 TypeInt::make(lo, hi, widen)); | |
1890 | |
1891 return _gvn.transform(cmov); | |
1892 | |
1893 /* | |
1894 // This is not as desirable as it may seem, since Min and Max | |
1895 // nodes do not have a full set of optimizations. | |
1896 // And they would interfere, anyway, with 'if' optimizations | |
1897 // and with CMoveI canonical forms. | |
1898 switch (id) { | |
1899 case vmIntrinsics::_min: | |
1900 result_val = _gvn.transform(new (C, 3) MinINode(x,y)); break; | |
1901 case vmIntrinsics::_max: | |
1902 result_val = _gvn.transform(new (C, 3) MaxINode(x,y)); break; | |
1903 default: | |
1904 ShouldNotReachHere(); | |
1905 } | |
1906 */ | |
1907 } | |
1908 | |
1909 inline int | |
1910 LibraryCallKit::classify_unsafe_addr(Node* &base, Node* &offset) { | |
1911 const TypePtr* base_type = TypePtr::NULL_PTR; | |
1912 if (base != NULL) base_type = _gvn.type(base)->isa_ptr(); | |
1913 if (base_type == NULL) { | |
1914 // Unknown type. | |
1915 return Type::AnyPtr; | |
1916 } else if (base_type == TypePtr::NULL_PTR) { | |
1917 // Since this is a NULL+long form, we have to switch to a rawptr. | |
1918 base = _gvn.transform( new (C, 2) CastX2PNode(offset) ); | |
1919 offset = MakeConX(0); | |
1920 return Type::RawPtr; | |
1921 } else if (base_type->base() == Type::RawPtr) { | |
1922 return Type::RawPtr; | |
1923 } else if (base_type->isa_oopptr()) { | |
1924 // Base is never null => always a heap address. | |
1925 if (base_type->ptr() == TypePtr::NotNull) { | |
1926 return Type::OopPtr; | |
1927 } | |
1928 // Offset is small => always a heap address. | |
1929 const TypeX* offset_type = _gvn.type(offset)->isa_intptr_t(); | |
1930 if (offset_type != NULL && | |
1931 base_type->offset() == 0 && // (should always be?) | |
1932 offset_type->_lo >= 0 && | |
1933 !MacroAssembler::needs_explicit_null_check(offset_type->_hi)) { | |
1934 return Type::OopPtr; | |
1935 } | |
1936 // Otherwise, it might either be oop+off or NULL+addr. | |
1937 return Type::AnyPtr; | |
1938 } else { | |
1939 // No information: | |
1940 return Type::AnyPtr; | |
1941 } | |
1942 } | |
1943 | |
1944 inline Node* LibraryCallKit::make_unsafe_address(Node* base, Node* offset) { | |
1945 int kind = classify_unsafe_addr(base, offset); | |
1946 if (kind == Type::RawPtr) { | |
1947 return basic_plus_adr(top(), base, offset); | |
1948 } else { | |
1949 return basic_plus_adr(base, offset); | |
1950 } | |
1951 } | |
1952 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1953 //-------------------inline_numberOfLeadingZeros_int/long----------------------- |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1954 // inline int Integer.numberOfLeadingZeros(int) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1955 // inline int Long.numberOfLeadingZeros(long) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1956 bool LibraryCallKit::inline_numberOfLeadingZeros(vmIntrinsics::ID id) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1957 assert(id == vmIntrinsics::_numberOfLeadingZeros_i || id == vmIntrinsics::_numberOfLeadingZeros_l, "not numberOfLeadingZeros"); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1958 if (id == vmIntrinsics::_numberOfLeadingZeros_i && !Matcher::match_rule_supported(Op_CountLeadingZerosI)) return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1959 if (id == vmIntrinsics::_numberOfLeadingZeros_l && !Matcher::match_rule_supported(Op_CountLeadingZerosL)) return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1960 _sp += arg_size(); // restore stack pointer |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1961 switch (id) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1962 case vmIntrinsics::_numberOfLeadingZeros_i: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1963 push(_gvn.transform(new (C, 2) CountLeadingZerosINode(pop()))); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1964 break; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1965 case vmIntrinsics::_numberOfLeadingZeros_l: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1966 push(_gvn.transform(new (C, 2) CountLeadingZerosLNode(pop_pair()))); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1967 break; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1968 default: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1969 ShouldNotReachHere(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1970 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1971 return true; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1972 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1973 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1974 //-------------------inline_numberOfTrailingZeros_int/long---------------------- |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1975 // inline int Integer.numberOfTrailingZeros(int) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1976 // inline int Long.numberOfTrailingZeros(long) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1977 bool LibraryCallKit::inline_numberOfTrailingZeros(vmIntrinsics::ID id) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1978 assert(id == vmIntrinsics::_numberOfTrailingZeros_i || id == vmIntrinsics::_numberOfTrailingZeros_l, "not numberOfTrailingZeros"); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1979 if (id == vmIntrinsics::_numberOfTrailingZeros_i && !Matcher::match_rule_supported(Op_CountTrailingZerosI)) return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1980 if (id == vmIntrinsics::_numberOfTrailingZeros_l && !Matcher::match_rule_supported(Op_CountTrailingZerosL)) return false; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1981 _sp += arg_size(); // restore stack pointer |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1982 switch (id) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1983 case vmIntrinsics::_numberOfTrailingZeros_i: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1984 push(_gvn.transform(new (C, 2) CountTrailingZerosINode(pop()))); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1985 break; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1986 case vmIntrinsics::_numberOfTrailingZeros_l: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1987 push(_gvn.transform(new (C, 2) CountTrailingZerosLNode(pop_pair()))); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1988 break; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1989 default: |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1990 ShouldNotReachHere(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1991 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1992 return true; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1993 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
730
diff
changeset
|
1994 |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
1995 //----------------------------inline_bitCount_int/long----------------------- |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
1996 // inline int Integer.bitCount(int) |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
1997 // inline int Long.bitCount(long) |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
1998 bool LibraryCallKit::inline_bitCount(vmIntrinsics::ID id) { |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
1999 assert(id == vmIntrinsics::_bitCount_i || id == vmIntrinsics::_bitCount_l, "not bitCount"); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2000 if (id == vmIntrinsics::_bitCount_i && !Matcher::has_match_rule(Op_PopCountI)) return false; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2001 if (id == vmIntrinsics::_bitCount_l && !Matcher::has_match_rule(Op_PopCountL)) return false; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2002 _sp += arg_size(); // restore stack pointer |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2003 switch (id) { |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2004 case vmIntrinsics::_bitCount_i: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2005 push(_gvn.transform(new (C, 2) PopCountINode(pop()))); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2006 break; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2007 case vmIntrinsics::_bitCount_l: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2008 push(_gvn.transform(new (C, 2) PopCountLNode(pop_pair()))); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2009 break; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2010 default: |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2011 ShouldNotReachHere(); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2012 } |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2013 return true; |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2014 } |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
605
diff
changeset
|
2015 |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2016 //----------------------------inline_reverseBytes_int/long/char/short------------------- |
605 | 2017 // inline Integer.reverseBytes(int) |
2018 // inline Long.reverseBytes(long) | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2019 // inline Character.reverseBytes(char) |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2020 // inline Short.reverseBytes(short) |
0 | 2021 bool LibraryCallKit::inline_reverseBytes(vmIntrinsics::ID id) { |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2022 assert(id == vmIntrinsics::_reverseBytes_i || id == vmIntrinsics::_reverseBytes_l || |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2023 id == vmIntrinsics::_reverseBytes_c || id == vmIntrinsics::_reverseBytes_s, |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2024 "not reverse Bytes"); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2025 if (id == vmIntrinsics::_reverseBytes_i && !Matcher::has_match_rule(Op_ReverseBytesI)) return false; |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2026 if (id == vmIntrinsics::_reverseBytes_l && !Matcher::has_match_rule(Op_ReverseBytesL)) return false; |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2027 if (id == vmIntrinsics::_reverseBytes_c && !Matcher::has_match_rule(Op_ReverseBytesUS)) return false; |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2028 if (id == vmIntrinsics::_reverseBytes_s && !Matcher::has_match_rule(Op_ReverseBytesS)) return false; |
0 | 2029 _sp += arg_size(); // restore stack pointer |
2030 switch (id) { | |
2031 case vmIntrinsics::_reverseBytes_i: | |
2032 push(_gvn.transform(new (C, 2) ReverseBytesINode(0, pop()))); | |
2033 break; | |
2034 case vmIntrinsics::_reverseBytes_l: | |
2035 push_pair(_gvn.transform(new (C, 2) ReverseBytesLNode(0, pop_pair()))); | |
2036 break; | |
1396
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2037 case vmIntrinsics::_reverseBytes_c: |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2038 push(_gvn.transform(new (C, 2) ReverseBytesUSNode(0, pop()))); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2039 break; |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2040 case vmIntrinsics::_reverseBytes_s: |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2041 push(_gvn.transform(new (C, 2) ReverseBytesSNode(0, pop()))); |
d7f654633cfe
6946040: add intrinsic for short and char reverseBytes
never
parents:
1152
diff
changeset
|
2042 break; |
0 | 2043 default: |
2044 ; | |
2045 } | |
2046 return true; | |
2047 } | |
2048 | |
2049 //----------------------------inline_unsafe_access---------------------------- | |
2050 | |
2051 const static BasicType T_ADDRESS_HOLDER = T_LONG; | |
2052 | |
2053 // Interpret Unsafe.fieldOffset cookies correctly: | |
2054 extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); | |
2055 | |
2056 bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile) { | |
2057 if (callee()->is_static()) return false; // caller must have the capability! | |
2058 | |
2059 #ifndef PRODUCT | |
2060 { | |
2061 ResourceMark rm; | |
2062 // Check the signatures. | |
2063 ciSignature* sig = signature(); | |
2064 #ifdef ASSERT | |
2065 if (!is_store) { | |
2066 // Object getObject(Object base, int/long offset), etc. | |
2067 BasicType rtype = sig->return_type()->basic_type(); | |
2068 if (rtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::getAddress_name()) | |
2069 rtype = T_ADDRESS; // it is really a C void* | |
2070 assert(rtype == type, "getter must return the expected value"); | |
2071 if (!is_native_ptr) { | |
2072 assert(sig->count() == 2, "oop getter has 2 arguments"); | |
2073 assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object"); | |
2074 assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct"); | |
2075 } else { | |
2076 assert(sig->count() == 1, "native getter has 1 argument"); | |
2077 assert(sig->type_at(0)->basic_type() == T_LONG, "getter base is long"); | |
2078 } | |
2079 } else { | |
2080 // void putObject(Object base, int/long offset, Object x), etc. | |
2081 assert(sig->return_type()->basic_type() == T_VOID, "putter must not return a value"); | |
2082 if (!is_native_ptr) { | |
2083 assert(sig->count() == 3, "oop putter has 3 arguments"); | |
2084 assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object"); | |
2085 assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct"); | |
2086 } else { | |
2087 assert(sig->count() == 2, "native putter has 2 arguments"); | |
2088 assert(sig->type_at(0)->basic_type() == T_LONG, "putter base is long"); | |
2089 } | |
2090 BasicType vtype = sig->type_at(sig->count()-1)->basic_type(); | |
2091 if (vtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::putAddress_name()) | |
2092 vtype = T_ADDRESS; // it is really a C void* | |
2093 assert(vtype == type, "putter must accept the expected value"); | |
2094 } | |
2095 #endif // ASSERT | |
2096 } | |
2097 #endif //PRODUCT | |
2098 | |
2099 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". | |
2100 | |
2101 int type_words = type2size[ (type == T_ADDRESS) ? T_LONG : type ]; | |
2102 | |
2103 // Argument words: "this" plus (oop/offset) or (lo/hi) args plus maybe 1 or 2 value words | |
2104 int nargs = 1 + (is_native_ptr ? 2 : 3) + (is_store ? type_words : 0); | |
2105 | |
2106 debug_only(int saved_sp = _sp); | |
2107 _sp += nargs; | |
2108 | |
2109 Node* val; | |
2110 debug_only(val = (Node*)(uintptr_t)-1); | |
2111 | |
2112 | |
2113 if (is_store) { | |
2114 // Get the value being stored. (Pop it first; it was pushed last.) | |
2115 switch (type) { | |
2116 case T_DOUBLE: | |
2117 case T_LONG: | |
2118 case T_ADDRESS: | |
2119 val = pop_pair(); | |
2120 break; | |
2121 default: | |
2122 val = pop(); | |
2123 } | |
2124 } | |
2125 | |
2126 // Build address expression. See the code in inline_unsafe_prefetch. | |
2127 Node *adr; | |
2128 Node *heap_base_oop = top(); | |
2129 if (!is_native_ptr) { | |
2130 // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset | |
2131 Node* offset = pop_pair(); | |
2132 // The base is either a Java object or a value produced by Unsafe.staticFieldBase | |
2133 Node* base = pop(); | |
2134 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset | |
2135 // to be plain byte offsets, which are also the same as those accepted | |
2136 // by oopDesc::field_base. | |
2137 assert(Unsafe_field_offset_to_byte_offset(11) == 11, | |
2138 "fieldOffset must be byte-scaled"); | |
2139 // 32-bit machines ignore the high half! | |
2140 offset = ConvL2X(offset); | |
2141 adr = make_unsafe_address(base, offset); | |
2142 heap_base_oop = base; | |
2143 } else { | |
2144 Node* ptr = pop_pair(); | |
2145 // Adjust Java long to machine word: | |
2146 ptr = ConvL2X(ptr); | |
2147 adr = make_unsafe_address(NULL, ptr); | |
2148 } | |
2149 | |
2150 // Pop receiver last: it was pushed first. | |
2151 Node *receiver = pop(); | |
2152 | |
2153 assert(saved_sp == _sp, "must have correct argument count"); | |
2154 | |
2155 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); | |
2156 | |
2157 // First guess at the value type. | |
2158 const Type *value_type = Type::get_const_basic_type(type); | |
2159 | |
2160 // Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM, | |
2161 // there was not enough information to nail it down. | |
2162 Compile::AliasType* alias_type = C->alias_type(adr_type); | |
2163 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here"); | |
2164 | |
2165 // We will need memory barriers unless we can determine a unique | |
2166 // alias category for this reference. (Note: If for some reason | |
2167 // the barriers get omitted and the unsafe reference begins to "pollute" | |
2168 // the alias analysis of the rest of the graph, either Compile::can_alias | |
2169 // or Compile::must_alias will throw a diagnostic assert.) | |
2170 bool need_mem_bar = (alias_type->adr_type() == TypeOopPtr::BOTTOM); | |
2171 | |
2172 if (!is_store && type == T_OBJECT) { | |
2173 // Attempt to infer a sharper value type from the offset and base type. | |
2174 ciKlass* sharpened_klass = NULL; | |
2175 | |
2176 // See if it is an instance field, with an object type. | |
2177 if (alias_type->field() != NULL) { | |
2178 assert(!is_native_ptr, "native pointer op cannot use a java address"); | |
2179 if (alias_type->field()->type()->is_klass()) { | |
2180 sharpened_klass = alias_type->field()->type()->as_klass(); | |
2181 } | |
2182 } | |
2183 | |
2184 // See if it is a narrow oop array. | |
2185 if (adr_type->isa_aryptr()) { | |
895
94b6d06fd759
6860920: serialize.cpp shouldn't use objArrayOopDesc::base_offset_in_bytes(T_BYTE)
twisti
parents:
851
diff
changeset
|
2186 if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes()) { |
0 | 2187 const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr(); |
2188 if (elem_type != NULL) { | |
2189 sharpened_klass = elem_type->klass(); | |
2190 } | |
2191 } | |
2192 } | |
2193 | |
2194 if (sharpened_klass != NULL) { | |
2195 const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); | |
2196 | |
2197 // Sharpen the value type. | |
2198 value_type = tjp; | |
2199 | |
2200 #ifndef PRODUCT | |
2201 if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { | |
2202 tty->print(" from base type: "); adr_type->dump(); | |
2203 tty->print(" sharpened value: "); value_type->dump(); | |
2204 } | |
2205 #endif | |
2206 } | |
2207 } | |
2208 | |
2209 // Null check on self without removing any arguments. The argument | |
2210 // null check technically happens in the wrong place, which can lead to | |
2211 // invalid stack traces when the primitive is inlined into a method | |
2212 // which handles NullPointerExceptions. | |
2213 _sp += nargs; | |
2214 do_null_check(receiver, T_OBJECT); | |
2215 _sp -= nargs; | |
2216 if (stopped()) { | |
2217 return true; | |
2218 } | |
2219 // Heap pointers get a null-check from the interpreter, | |
2220 // as a courtesy. However, this is not guaranteed by Unsafe, | |
2221 // and it is not possible to fully distinguish unintended nulls | |
2222 // from intended ones in this API. | |
2223 | |
2224 if (is_volatile) { | |
2225 // We need to emit leading and trailing CPU membars (see below) in | |
2226 // addition to memory membars when is_volatile. This is a little | |
2227 // too strong, but avoids the need to insert per-alias-type | |
2228 // volatile membars (for stores; compare Parse::do_put_xxx), which | |
605 | 2229 // we cannot do effectively here because we probably only have a |
0 | 2230 // rough approximation of type. |
2231 need_mem_bar = true; | |
2232 // For Stores, place a memory ordering barrier now. | |
2233 if (is_store) | |
2234 insert_mem_bar(Op_MemBarRelease); | |
2235 } | |
2236 | |
2237 // Memory barrier to prevent normal and 'unsafe' accesses from | |
2238 // bypassing each other. Happens after null checks, so the | |
2239 // exception paths do not take memory state from the memory barrier, | |
2240 // so there's no problems making a strong assert about mixing users | |
2241 // of safe & unsafe memory. Otherwise fails in a CTW of rt.jar | |
2242 // around 5701, class sun/reflect/UnsafeBooleanFieldAccessorImpl. | |
2243 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder); | |
2244 | |
2245 if (!is_store) { | |
2246 Node* p = make_load(control(), adr, value_type, type, adr_type, is_volatile); | |
2247 // load value and push onto stack | |
2248 switch (type) { | |
2249 case T_BOOLEAN: | |
2250 case T_CHAR: | |
2251 case T_BYTE: | |
2252 case T_SHORT: | |
2253 case T_INT: | |
2254 case T_FLOAT: | |
2255 case T_OBJECT: | |
2256 push( p ); | |
2257 break; | |
2258 case T_ADDRESS: | |
2259 // Cast to an int type. | |
2260 p = _gvn.transform( new (C, 2) CastP2XNode(NULL,p) ); | |
2261 p = ConvX2L(p); | |
2262 push_pair(p); | |
2263 break; | |
2264 case T_DOUBLE: | |
2265 case T_LONG: | |
2266 push_pair( p ); | |
2267 break; | |
2268 default: ShouldNotReachHere(); | |
2269 } | |
2270 } else { | |
2271 // place effect of store into memory | |
2272 switch (type) { | |
2273 case T_DOUBLE: | |
2274 val = dstore_rounding(val); | |
2275 break; | |
2276 case T_ADDRESS: | |
2277 // Repackage the long as a pointer. | |
2278 val = ConvL2X(val); | |
2279 val = _gvn.transform( new (C, 2) CastX2PNode(val) ); | |
2280 break; | |
2281 } | |
2282 | |
2283 if (type != T_OBJECT ) { | |
2284 (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile); | |
2285 } else { | |
2286 // Possibly an oop being stored to Java heap or native memory | |
2287 if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) { | |
2288 // oop to Java heap. | |
825 | 2289 (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type); |
0 | 2290 } else { |
2291 // We can't tell at compile time if we are storing in the Java heap or outside | |
2292 // of it. So we need to emit code to conditionally do the proper type of | |
2293 // store. | |
2294 | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2295 IdealKit ideal(gvn(), control(), merged_memory()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2296 #define __ ideal. |
0 | 2297 // QQQ who knows what probability is here?? |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2298 __ 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
|
2299 // Sync IdealKit and graphKit. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2300 set_all_memory( __ merged_memory()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2301 set_control(__ ctrl()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2302 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
|
2303 // Update IdealKit memory. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2304 __ set_all_memory(merged_memory()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2305 __ set_ctrl(control()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2306 } __ else_(); { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2307 __ 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
|
2308 } __ end_if(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2309 // Final sync IdealKit and GraphKit. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2310 sync_kit(ideal); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
836
diff
changeset
|
2311 #undef __ |
0 | 2312 } |
2313 } | |
2314 } | |
2315 | |
2316 if (is_volatile) { | |
2317 if (!is_store) | |
2318 insert_mem_bar(Op_MemBarAcquire); | |
2319 else | |
2320 insert_mem_bar(Op_MemBarVolatile); | |
2321 } | |
2322 | |
2323 if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder); | |
2324 | |
2325 return true; | |
2326 } | |
2327 | |
2328 //----------------------------inline_unsafe_prefetch---------------------------- | |
2329 | |
2330 bool LibraryCallKit::inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static) { | |
2331 #ifndef PRODUCT | |
2332 { | |
2333 ResourceMark rm; | |
2334 // Check the signatures. | |
2335 ciSignature* sig = signature(); | |
2336 #ifdef ASSERT | |
2337 // Object getObject(Object base, int/long offset), etc. | |
2338 BasicType rtype = sig->return_type()->basic_type(); | |
2339 if (!is_native_ptr) { | |
2340 assert(sig->count() == 2, "oop prefetch has 2 arguments"); | |
2341 assert(sig->type_at(0)->basic_type() == T_OBJECT, "prefetch base is object"); | |
2342 assert(sig->type_at(1)->basic_type() == T_LONG, "prefetcha offset is correct"); | |
2343 } else { | |
2344 assert(sig->count() == 1, "native prefetch has 1 argument"); | |
2345 assert(sig->type_at(0)->basic_type() == T_LONG, "prefetch base is long"); | |
2346 } | |
2347 #endif // ASSERT | |
2348 } | |
2349 #endif // !PRODUCT | |
2350 | |
2351 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". | |
2352 | |
2353 // Argument words: "this" if not static, plus (oop/offset) or (lo/hi) args | |
2354 int nargs = (is_static ? 0 : 1) + (is_native_ptr ? 2 : 3); | |
2355 | |
2356 debug_only(int saved_sp = _sp); | |
2357 _sp += nargs; | |
2358 | |
2359 // Build address expression. See the code in inline_unsafe_access. | |
2360 Node *adr; | |
2361 if (!is_native_ptr) { | |
2362 // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset | |
2363 Node* offset = pop_pair(); | |
2364 // The base is either a Java object or a value produced by Unsafe.staticFieldBase | |
2365 Node* base = pop(); | |
2366 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset | |
2367 // to be plain byte offsets, which are also the same as those accepted | |
2368 // by oopDesc::field_base. | |
2369 assert(Unsafe_field_offset_to_byte_offset(11) == 11, | |
2370 "fieldOffset must be byte-scaled"); | |
2371 // 32-bit machines ignore the high half! | |
2372 offset = ConvL2X(offset); | |
2373 adr = make_unsafe_address(base, offset); | |
2374 } else { | |
2375 Node* ptr = pop_pair(); | |
2376 // Adjust Java long to machine word: | |
2377 ptr = ConvL2X(ptr); | |
2378 adr = make_unsafe_address(NULL, ptr); | |
2379 } | |
2380 | |
2381 if (is_static) { | |
2382 assert(saved_sp == _sp, "must have correct argument count"); | |
2383 } else { | |
2384 // Pop receiver last: it was pushed first. | |
2385 Node *receiver = pop(); | |
2386 assert(saved_sp == _sp, "must have correct argument count"); | |
2387 | |
2388 // Null check on self without removing any arguments. The argument | |
2389 // null check technically happens in the wrong place, which can lead to | |
2390 // invalid stack traces when the primitive is inlined into a method | |
2391 // which handles NullPointerExceptions. | |
2392 _sp += nargs; | |
2393 do_null_check(receiver, T_OBJECT); | |
2394 _sp -= nargs; | |
2395 if (stopped()) { | |
2396 return true; | |
2397 } | |
2398 } | |
2399 | |
2400 // Generate the read or write prefetch | |
2401 Node *prefetch; | |
2402 if (is_store) { | |
2403 prefetch = new (C, 3) PrefetchWriteNode(i_o(), adr); | |
2404 } else { | |
2405 prefetch = new (C, 3) PrefetchReadNode(i_o(), adr); | |
2406 } | |
2407 prefetch->init_req(0, control()); | |
2408 set_i_o(_gvn.transform(prefetch)); | |
2409 | |
2410 return true; | |
2411 } | |
2412 | |
2413 //----------------------------inline_unsafe_CAS---------------------------- | |
2414 | |
2415 bool LibraryCallKit::inline_unsafe_CAS(BasicType type) { | |
2416 // This basic scheme here is the same as inline_unsafe_access, but | |
2417 // differs in enough details that combining them would make the code | |
2418 // overly confusing. (This is a true fact! I originally combined | |
2419 // them, but even I was confused by it!) As much code/comments as | |
2420 // possible are retained from inline_unsafe_access though to make | |
605 | 2421 // the correspondences clearer. - dl |
0 | 2422 |
2423 if (callee()->is_static()) return false; // caller must have the capability! | |
2424 | |
2425 #ifndef PRODUCT | |
2426 { | |
2427 ResourceMark rm; | |
2428 // Check the signatures. | |
2429 ciSignature* sig = signature(); | |
2430 #ifdef ASSERT | |
2431 BasicType rtype = sig->return_type()->basic_type(); | |
2432 assert(rtype == T_BOOLEAN, "CAS must return boolean"); | |
2433 assert(sig->count() == 4, "CAS has 4 arguments"); | |
2434 assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object"); | |
2435 assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long"); | |
2436 #endif // ASSERT | |
2437 } | |
2438 #endif //PRODUCT | |
2439 | |
2440 // number of stack slots per value argument (1 or 2) | |
2441 int type_words = type2size[type]; | |
2442 | |
2443 // Cannot inline wide CAS on machines that don't support it natively | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
2444 if (type2aelembytes(type) > BytesPerInt && !VM_Version::supports_cx8()) |
0 | 2445 return false; |
2446 | |
2447 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". | |
2448 | |
2449 // Argument words: "this" plus oop plus offset plus oldvalue plus newvalue; | |
2450 int nargs = 1 + 1 + 2 + type_words + type_words; | |
2451 | |
2452 // pop arguments: newval, oldval, offset, base, and receiver | |
2453 debug_only(int saved_sp = _sp); | |
2454 _sp += nargs; | |
2455 Node* newval = (type_words == 1) ? pop() : pop_pair(); | |
2456 Node* oldval = (type_words == 1) ? pop() : pop_pair(); | |
2457 Node *offset = pop_pair(); | |
2458 Node *base = pop(); | |
2459 Node *receiver = pop(); | |
2460 assert(saved_sp == _sp, "must have correct argument count"); | |
2461 | |
2462 // Null check receiver. | |
2463 _sp += nargs; | |
2464 do_null_check(receiver, T_OBJECT); | |
2465 _sp -= nargs; | |
2466 if (stopped()) { | |
2467 return true; | |
2468 } | |
2469 | |
2470 // Build field offset expression. | |
2471 // We currently rely on the cookies produced by Unsafe.xxxFieldOffset | |
2472 // to be plain byte offsets, which are also the same as those accepted | |
2473 // by oopDesc::field_base. | |
2474 assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled"); | |
2475 // 32-bit machines ignore the high half of long offsets | |
2476 offset = ConvL2X(offset); | |
2477 Node* adr = make_unsafe_address(base, offset); | |
2478 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); | |
2479 | |
2480 // (Unlike inline_unsafe_access, there seems no point in trying | |
2481 // to refine types. Just use the coarse types here. | |
2482 const Type *value_type = Type::get_const_basic_type(type); | |
2483 Compile::AliasType* alias_type = C->alias_type(adr_type); | |
2484 assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here"); | |
2485 int alias_idx = C->get_alias_index(adr_type); | |
2486 | |
2487 // Memory-model-wise, a CAS acts like a little synchronized block, | |
605 | 2488 // so needs barriers on each side. These don't translate into |
0 | 2489 // actual barriers on most machines, but we still need rest of |
2490 // compiler to respect ordering. | |
2491 | |
2492 insert_mem_bar(Op_MemBarRelease); | |
2493 insert_mem_bar(Op_MemBarCPUOrder); | |
2494 | |
2495 // 4984716: MemBars must be inserted before this | |
2496 // memory node in order to avoid a false | |
2497 // dependency which will confuse the scheduler. | |
2498 Node *mem = memory(alias_idx); | |
2499 | |
2500 // For now, we handle only those cases that actually exist: ints, | |
2501 // longs, and Object. Adding others should be straightforward. | |
2502 Node* cas; | |
2503 switch(type) { | |
2504 case T_INT: | |
2505 cas = _gvn.transform(new (C, 5) CompareAndSwapINode(control(), mem, adr, newval, oldval)); | |
2506 break; | |
2507 case T_LONG: | |
2508 cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); | |
2509 break; | |
2510 case T_OBJECT: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
2511 // reference stores need a store barrier. |
0 | 2512 // (They don't if CAS fails, but it isn't worth checking.) |
827
bf3489cc0aa0
6856025: assert(_base >= OopPtr && _base <= KlassPtr,"Not a Java pointer")
never
parents:
825
diff
changeset
|
2513 pre_barrier(control(), base, adr, alias_idx, newval, value_type->make_oopptr(), T_OBJECT); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
2514 #ifdef _LP64 |
163 | 2515 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
174
diff
changeset
|
2516 Node *newval_enc = _gvn.transform(new (C, 2) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
174
diff
changeset
|
2517 Node *oldval_enc = _gvn.transform(new (C, 2) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop())); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
2518 cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr, |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
174
diff
changeset
|
2519 newval_enc, oldval_enc)); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
2520 } else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
2521 #endif |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
174
diff
changeset
|
2522 { |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
174
diff
changeset
|
2523 cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
174
diff
changeset
|
2524 } |
0 | 2525 post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true); |
2526 break; | |
2527 default: | |
2528 ShouldNotReachHere(); | |
2529 break; | |
2530 } | |
2531 | |
2532 // SCMemProjNodes represent the memory state of CAS. Their main | |
2533 // role is to prevent CAS nodes from being optimized away when their | |
2534 // results aren't used. | |
2535 Node* proj = _gvn.transform( new (C, 1) SCMemProjNode(cas)); | |
2536 set_memory(proj, alias_idx); | |
2537 | |
2538 // Add the trailing membar surrounding the access | |
2539 insert_mem_bar(Op_MemBarCPUOrder); | |
2540 insert_mem_bar(Op_MemBarAcquire); | |
2541 | |
2542 push(cas); | |
2543 return true; | |
2544 } | |
2545 | |
2546 bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) { | |
2547 // This is another variant of inline_unsafe_access, differing in | |
2548 // that it always issues store-store ("release") barrier and ensures | |
2549 // store-atomicity (which only matters for "long"). | |
2550 | |
2551 if (callee()->is_static()) return false; // caller must have the capability! | |
2552 | |
2553 #ifndef PRODUCT | |
2554 { | |
2555 ResourceMark rm; | |
2556 // Check the signatures. | |
2557 ciSignature* sig = signature(); | |
2558 #ifdef ASSERT | |
2559 BasicType rtype = sig->return_type()->basic_type(); | |
2560 assert(rtype == T_VOID, "must return void"); | |
2561 assert(sig->count() == 3, "has 3 arguments"); | |
2562 assert(sig->type_at(0)->basic_type() == T_OBJECT, "base is object"); | |
2563 assert(sig->type_at(1)->basic_type() == T_LONG, "offset is long"); | |
2564 #endif // ASSERT | |
2565 } | |
2566 #endif //PRODUCT | |
2567 | |
2568 // number of stack slots per value argument (1 or 2) | |
2569 int type_words = type2size[type]; | |
2570 | |
2571 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". | |
2572 | |
2573 // Argument words: "this" plus oop plus offset plus value; | |
2574 int nargs = 1 + 1 + 2 + type_words; | |
2575 | |
2576 // pop arguments: val, offset, base, and receiver | |
2577 debug_only(int saved_sp = _sp); | |
2578 _sp += nargs; | |
2579 Node* val = (type_words == 1) ? pop() : pop_pair(); | |
2580 Node *offset = pop_pair(); | |
2581 Node *base = pop(); | |
2582 Node *receiver = pop(); | |
2583 assert(saved_sp == _sp, "must have correct argument count"); | |
2584 | |
2585 // Null check receiver. | |
2586 _sp += nargs; | |
2587 do_null_check(receiver, T_OBJECT); | |
2588 _sp -= nargs; | |
2589 if (stopped()) { | |
2590 return true; | |
2591 } | |
2592 | |
2593 // Build field offset expression. | |
2594 assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled"); | |
2595 // 32-bit machines ignore the high half of long offsets | |
2596 offset = ConvL2X(offset); | |
2597 Node* adr = make_unsafe_address(base, offset); | |
2598 const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); | |
2599 const Type *value_type = Type::get_const_basic_type(type); | |
2600 Compile::AliasType* alias_type = C->alias_type(adr_type); | |
2601 | |
2602 insert_mem_bar(Op_MemBarRelease); | |
2603 insert_mem_bar(Op_MemBarCPUOrder); | |
2604 // Ensure that the store is atomic for longs: | |
2605 bool require_atomic_access = true; | |
2606 Node* store; | |
2607 if (type == T_OBJECT) // reference stores need a store barrier. | |
825 | 2608 store = store_oop_to_unknown(control(), base, adr, adr_type, val, type); |
0 | 2609 else { |
2610 store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access); | |
2611 } | |
2612 insert_mem_bar(Op_MemBarCPUOrder); | |
2613 return true; | |
2614 } | |
2615 | |
2616 bool LibraryCallKit::inline_unsafe_allocate() { | |
2617 if (callee()->is_static()) return false; // caller must have the capability! | |
2618 int nargs = 1 + 1; | |
2619 assert(signature()->size() == nargs-1, "alloc has 1 argument"); | |
2620 null_check_receiver(callee()); // check then ignore argument(0) | |
2621 _sp += nargs; // set original stack for use by uncommon_trap | |
2622 Node* cls = do_null_check(argument(1), T_OBJECT); | |
2623 _sp -= nargs; | |
2624 if (stopped()) return true; | |
2625 | |
2626 Node* kls = load_klass_from_mirror(cls, false, nargs, NULL, 0); | |
2627 _sp += nargs; // set original stack for use by uncommon_trap | |
2628 kls = do_null_check(kls, T_OBJECT); | |
2629 _sp -= nargs; | |
2630 if (stopped()) return true; // argument was like int.class | |
2631 | |
2632 // Note: The argument might still be an illegal value like | |
2633 // Serializable.class or Object[].class. The runtime will handle it. | |
2634 // But we must make an explicit check for initialization. | |
2635 Node* insp = basic_plus_adr(kls, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)); | |
2636 Node* inst = make_load(NULL, insp, TypeInt::INT, T_INT); | |
2637 Node* bits = intcon(instanceKlass::fully_initialized); | |
2638 Node* test = _gvn.transform( new (C, 3) SubINode(inst, bits) ); | |
2639 // The 'test' is non-zero if we need to take a slow path. | |
2640 | |
2641 Node* obj = new_instance(kls, test); | |
2642 push(obj); | |
2643 | |
2644 return true; | |
2645 } | |
2646 | |
2647 //------------------------inline_native_time_funcs-------------- | |
2648 // inline code for System.currentTimeMillis() and System.nanoTime() | |
2649 // these have the same type and signature | |
2650 bool LibraryCallKit::inline_native_time_funcs(bool isNano) { | |
2651 address funcAddr = isNano ? CAST_FROM_FN_PTR(address, os::javaTimeNanos) : | |
2652 CAST_FROM_FN_PTR(address, os::javaTimeMillis); | |
2653 const char * funcName = isNano ? "nanoTime" : "currentTimeMillis"; | |
2654 const TypeFunc *tf = OptoRuntime::current_time_millis_Type(); | |
2655 const TypePtr* no_memory_effects = NULL; | |
2656 Node* time = make_runtime_call(RC_LEAF, tf, funcAddr, funcName, no_memory_effects); | |
2657 Node* value = _gvn.transform(new (C, 1) ProjNode(time, TypeFunc::Parms+0)); | |
2658 #ifdef ASSERT | |
2659 Node* value_top = _gvn.transform(new (C, 1) ProjNode(time, TypeFunc::Parms + 1)); | |
2660 assert(value_top == top(), "second value must be top"); | |
2661 #endif | |
2662 push_pair(value); | |
2663 return true; | |
2664 } | |
2665 | |
2666 //------------------------inline_native_currentThread------------------ | |
2667 bool LibraryCallKit::inline_native_currentThread() { | |
2668 Node* junk = NULL; | |
2669 push(generate_current_thread(junk)); | |
2670 return true; | |
2671 } | |
2672 | |
2673 //------------------------inline_native_isInterrupted------------------ | |
2674 bool LibraryCallKit::inline_native_isInterrupted() { | |
2675 const int nargs = 1+1; // receiver + boolean | |
2676 assert(nargs == arg_size(), "sanity"); | |
2677 // Add a fast path to t.isInterrupted(clear_int): | |
2678 // (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int)) | |
2679 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) | |
2680 // So, in the common case that the interrupt bit is false, | |
2681 // we avoid making a call into the VM. Even if the interrupt bit | |
2682 // is true, if the clear_int argument is false, we avoid the VM call. | |
2683 // However, if the receiver is not currentThread, we must call the VM, | |
2684 // because there must be some locking done around the operation. | |
2685 | |
2686 // We only go to the fast case code if we pass two guards. | |
2687 // Paths which do not pass are accumulated in the slow_region. | |
2688 RegionNode* slow_region = new (C, 1) RegionNode(1); | |
2689 record_for_igvn(slow_region); | |
2690 RegionNode* result_rgn = new (C, 4) RegionNode(1+3); // fast1, fast2, slow | |
2691 PhiNode* result_val = new (C, 4) PhiNode(result_rgn, TypeInt::BOOL); | |
2692 enum { no_int_result_path = 1, | |
2693 no_clear_result_path = 2, | |
2694 slow_result_path = 3 | |
2695 }; | |
2696 | |
2697 // (a) Receiving thread must be the current thread. | |
2698 Node* rec_thr = argument(0); | |
2699 Node* tls_ptr = NULL; | |
2700 Node* cur_thr = generate_current_thread(tls_ptr); | |
2701 Node* cmp_thr = _gvn.transform( new (C, 3) CmpPNode(cur_thr, rec_thr) ); | |
2702 Node* bol_thr = _gvn.transform( new (C, 2) BoolNode(cmp_thr, BoolTest::ne) ); | |
2703 | |
2704 bool known_current_thread = (_gvn.type(bol_thr) == TypeInt::ZERO); | |
2705 if (!known_current_thread) | |
2706 generate_slow_guard(bol_thr, slow_region); | |
2707 | |
2708 // (b) Interrupt bit on TLS must be false. | |
2709 Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset())); | |
2710 Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS); | |
2711 p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset())); | |
787
aabd393cf1ee
6772683: Thread.isInterrupted() fails to return true on multiprocessor PC
kvn
parents:
775
diff
changeset
|
2712 // 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
|
2713 Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT); |
0 | 2714 Node* cmp_bit = _gvn.transform( new (C, 3) CmpINode(int_bit, intcon(0)) ); |
2715 Node* bol_bit = _gvn.transform( new (C, 2) BoolNode(cmp_bit, BoolTest::ne) ); | |
2716 | |
2717 IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); | |
2718 | |
2719 // First fast path: if (!TLS._interrupted) return false; | |
2720 Node* false_bit = _gvn.transform( new (C, 1) IfFalseNode(iff_bit) ); | |
2721 result_rgn->init_req(no_int_result_path, false_bit); | |
2722 result_val->init_req(no_int_result_path, intcon(0)); | |
2723 | |
2724 // drop through to next case | |
2725 set_control( _gvn.transform(new (C, 1) IfTrueNode(iff_bit)) ); | |
2726 | |
2727 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. | |
2728 Node* clr_arg = argument(1); | |
2729 Node* cmp_arg = _gvn.transform( new (C, 3) CmpINode(clr_arg, intcon(0)) ); | |
2730 Node* bol_arg = _gvn.transform( new (C, 2) BoolNode(cmp_arg, BoolTest::ne) ); | |
2731 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); | |
2732 | |
2733 // Second fast path: ... else if (!clear_int) return true; | |
2734 Node* false_arg = _gvn.transform( new (C, 1) IfFalseNode(iff_arg) ); | |
2735 result_rgn->init_req(no_clear_result_path, false_arg); | |
2736 result_val->init_req(no_clear_result_path, intcon(1)); | |
2737 | |
2738 // drop through to next case | |
2739 set_control( _gvn.transform(new (C, 1) IfTrueNode(iff_arg)) ); | |
2740 | |
2741 // (d) Otherwise, go to the slow path. | |
2742 slow_region->add_req(control()); | |
2743 set_control( _gvn.transform(slow_region) ); | |
2744 | |
2745 if (stopped()) { | |
2746 // There is no slow path. | |
2747 result_rgn->init_req(slow_result_path, top()); | |
2748 result_val->init_req(slow_result_path, top()); | |
2749 } else { | |
2750 // non-virtual because it is a private non-static | |
2751 CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_isInterrupted); | |
2752 | |
2753 Node* slow_val = set_results_for_java_call(slow_call); | |
2754 // this->control() comes from set_results_for_java_call | |
2755 | |
2756 // If we know that the result of the slow call will be true, tell the optimizer! | |
2757 if (known_current_thread) slow_val = intcon(1); | |
2758 | |
2759 Node* fast_io = slow_call->in(TypeFunc::I_O); | |
2760 Node* fast_mem = slow_call->in(TypeFunc::Memory); | |
2761 // These two phis are pre-filled with copies of of the fast IO and Memory | |
2762 Node* io_phi = PhiNode::make(result_rgn, fast_io, Type::ABIO); | |
2763 Node* mem_phi = PhiNode::make(result_rgn, fast_mem, Type::MEMORY, TypePtr::BOTTOM); | |
2764 | |
2765 result_rgn->init_req(slow_result_path, control()); | |
2766 io_phi ->init_req(slow_result_path, i_o()); | |
2767 mem_phi ->init_req(slow_result_path, reset_memory()); | |
2768 result_val->init_req(slow_result_path, slow_val); | |
2769 | |
2770 set_all_memory( _gvn.transform(mem_phi) ); | |
2771 set_i_o( _gvn.transform(io_phi) ); | |
2772 } | |
2773 | |
2774 push_result(result_rgn, result_val); | |
2775 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
2776 | |
2777 return true; | |
2778 } | |
2779 | |
2780 //---------------------------load_mirror_from_klass---------------------------- | |
2781 // Given a klass oop, load its java mirror (a java.lang.Class oop). | |
2782 Node* LibraryCallKit::load_mirror_from_klass(Node* klass) { | |
2783 Node* p = basic_plus_adr(klass, Klass::java_mirror_offset_in_bytes() + sizeof(oopDesc)); | |
2784 return make_load(NULL, p, TypeInstPtr::MIRROR, T_OBJECT); | |
2785 } | |
2786 | |
2787 //-----------------------load_klass_from_mirror_common------------------------- | |
2788 // Given a java mirror (a java.lang.Class oop), load its corresponding klass oop. | |
2789 // Test the klass oop for null (signifying a primitive Class like Integer.TYPE), | |
2790 // and branch to the given path on the region. | |
2791 // If never_see_null, take an uncommon trap on null, so we can optimistically | |
2792 // compile for the non-null case. | |
2793 // If the region is NULL, force never_see_null = true. | |
2794 Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror, | |
2795 bool never_see_null, | |
2796 int nargs, | |
2797 RegionNode* region, | |
2798 int null_path, | |
2799 int offset) { | |
2800 if (region == NULL) never_see_null = true; | |
2801 Node* p = basic_plus_adr(mirror, offset); | |
2802 const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL; | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2803 Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type) ); |
0 | 2804 _sp += nargs; // any deopt will start just before call to enclosing method |
2805 Node* null_ctl = top(); | |
2806 kls = null_check_oop(kls, &null_ctl, never_see_null); | |
2807 if (region != NULL) { | |
2808 // Set region->in(null_path) if the mirror is a primitive (e.g, int.class). | |
2809 region->init_req(null_path, null_ctl); | |
2810 } else { | |
2811 assert(null_ctl == top(), "no loose ends"); | |
2812 } | |
2813 _sp -= nargs; | |
2814 return kls; | |
2815 } | |
2816 | |
2817 //--------------------(inline_native_Class_query helpers)--------------------- | |
2818 // Use this for JVM_ACC_INTERFACE, JVM_ACC_IS_CLONEABLE, JVM_ACC_HAS_FINALIZER. | |
2819 // Fall through if (mods & mask) == bits, take the guard otherwise. | |
2820 Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, int modifier_bits, RegionNode* region) { | |
2821 // Branch around if the given klass has the given modifier bit set. | |
2822 // Like generate_guard, adds a new path onto the region. | |
2823 Node* modp = basic_plus_adr(kls, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc)); | |
2824 Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT); | |
2825 Node* mask = intcon(modifier_mask); | |
2826 Node* bits = intcon(modifier_bits); | |
2827 Node* mbit = _gvn.transform( new (C, 3) AndINode(mods, mask) ); | |
2828 Node* cmp = _gvn.transform( new (C, 3) CmpINode(mbit, bits) ); | |
2829 Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) ); | |
2830 return generate_fair_guard(bol, region); | |
2831 } | |
2832 Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { | |
2833 return generate_access_flags_guard(kls, JVM_ACC_INTERFACE, 0, region); | |
2834 } | |
2835 | |
2836 //-------------------------inline_native_Class_query------------------- | |
2837 bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { | |
2838 int nargs = 1+0; // just the Class mirror, in most cases | |
2839 const Type* return_type = TypeInt::BOOL; | |
2840 Node* prim_return_value = top(); // what happens if it's a primitive class? | |
2841 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); | |
2842 bool expect_prim = false; // most of these guys expect to work on refs | |
2843 | |
2844 enum { _normal_path = 1, _prim_path = 2, PATH_LIMIT }; | |
2845 | |
2846 switch (id) { | |
2847 case vmIntrinsics::_isInstance: | |
2848 nargs = 1+1; // the Class mirror, plus the object getting queried about | |
2849 // nothing is an instance of a primitive type | |
2850 prim_return_value = intcon(0); | |
2851 break; | |
2852 case vmIntrinsics::_getModifiers: | |
2853 prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); | |
2854 assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line"); | |
2855 return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin); | |
2856 break; | |
2857 case vmIntrinsics::_isInterface: | |
2858 prim_return_value = intcon(0); | |
2859 break; | |
2860 case vmIntrinsics::_isArray: | |
2861 prim_return_value = intcon(0); | |
2862 expect_prim = true; // cf. ObjectStreamClass.getClassSignature | |
2863 break; | |
2864 case vmIntrinsics::_isPrimitive: | |
2865 prim_return_value = intcon(1); | |
2866 expect_prim = true; // obviously | |
2867 break; | |
2868 case vmIntrinsics::_getSuperclass: | |
2869 prim_return_value = null(); | |
2870 return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR); | |
2871 break; | |
2872 case vmIntrinsics::_getComponentType: | |
2873 prim_return_value = null(); | |
2874 return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR); | |
2875 break; | |
2876 case vmIntrinsics::_getClassAccessFlags: | |
2877 prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); | |
2878 return_type = TypeInt::INT; // not bool! 6297094 | |
2879 break; | |
2880 default: | |
2881 ShouldNotReachHere(); | |
2882 } | |
2883 | |
2884 Node* mirror = argument(0); | |
2885 Node* obj = (nargs <= 1)? top(): argument(1); | |
2886 | |
2887 const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr(); | |
2888 if (mirror_con == NULL) return false; // cannot happen? | |
2889 | |
2890 #ifndef PRODUCT | |
2891 if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { | |
2892 ciType* k = mirror_con->java_mirror_type(); | |
2893 if (k) { | |
2894 tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id())); | |
2895 k->print_name(); | |
2896 tty->cr(); | |
2897 } | |
2898 } | |
2899 #endif | |
2900 | |
2901 // Null-check the mirror, and the mirror's klass ptr (in case it is a primitive). | |
2902 RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
2903 record_for_igvn(region); | |
2904 PhiNode* phi = new (C, PATH_LIMIT) PhiNode(region, return_type); | |
2905 | |
2906 // The mirror will never be null of Reflection.getClassAccessFlags, however | |
2907 // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE | |
2908 // if it is. See bug 4774291. | |
2909 | |
2910 // For Reflection.getClassAccessFlags(), the null check occurs in | |
2911 // the wrong place; see inline_unsafe_access(), above, for a similar | |
2912 // situation. | |
2913 _sp += nargs; // set original stack for use by uncommon_trap | |
2914 mirror = do_null_check(mirror, T_OBJECT); | |
2915 _sp -= nargs; | |
2916 // If mirror or obj is dead, only null-path is taken. | |
2917 if (stopped()) return true; | |
2918 | |
2919 if (expect_prim) never_see_null = false; // expect nulls (meaning prims) | |
2920 | |
2921 // Now load the mirror's klass metaobject, and null-check it. | |
2922 // Side-effects region with the control path if the klass is null. | |
2923 Node* kls = load_klass_from_mirror(mirror, never_see_null, nargs, | |
2924 region, _prim_path); | |
2925 // If kls is null, we have a primitive mirror. | |
2926 phi->init_req(_prim_path, prim_return_value); | |
2927 if (stopped()) { push_result(region, phi); return true; } | |
2928 | |
2929 Node* p; // handy temp | |
2930 Node* null_ctl; | |
2931 | |
2932 // Now that we have the non-null klass, we can perform the real query. | |
2933 // For constant classes, the query will constant-fold in LoadNode::Value. | |
2934 Node* query_value = top(); | |
2935 switch (id) { | |
2936 case vmIntrinsics::_isInstance: | |
2937 // nothing is an instance of a primitive type | |
2938 query_value = gen_instanceof(obj, kls); | |
2939 break; | |
2940 | |
2941 case vmIntrinsics::_getModifiers: | |
2942 p = basic_plus_adr(kls, Klass::modifier_flags_offset_in_bytes() + sizeof(oopDesc)); | |
2943 query_value = make_load(NULL, p, TypeInt::INT, T_INT); | |
2944 break; | |
2945 | |
2946 case vmIntrinsics::_isInterface: | |
2947 // (To verify this code sequence, check the asserts in JVM_IsInterface.) | |
2948 if (generate_interface_guard(kls, region) != NULL) | |
2949 // A guard was added. If the guard is taken, it was an interface. | |
2950 phi->add_req(intcon(1)); | |
2951 // If we fall through, it's a plain class. | |
2952 query_value = intcon(0); | |
2953 break; | |
2954 | |
2955 case vmIntrinsics::_isArray: | |
2956 // (To verify this code sequence, check the asserts in JVM_IsArrayClass.) | |
2957 if (generate_array_guard(kls, region) != NULL) | |
2958 // A guard was added. If the guard is taken, it was an array. | |
2959 phi->add_req(intcon(1)); | |
2960 // If we fall through, it's a plain class. | |
2961 query_value = intcon(0); | |
2962 break; | |
2963 | |
2964 case vmIntrinsics::_isPrimitive: | |
2965 query_value = intcon(0); // "normal" path produces false | |
2966 break; | |
2967 | |
2968 case vmIntrinsics::_getSuperclass: | |
2969 // The rules here are somewhat unfortunate, but we can still do better | |
2970 // with random logic than with a JNI call. | |
2971 // Interfaces store null or Object as _super, but must report null. | |
2972 // Arrays store an intermediate super as _super, but must report Object. | |
2973 // Other types can report the actual _super. | |
2974 // (To verify this code sequence, check the asserts in JVM_IsInterface.) | |
2975 if (generate_interface_guard(kls, region) != NULL) | |
2976 // A guard was added. If the guard is taken, it was an interface. | |
2977 phi->add_req(null()); | |
2978 if (generate_array_guard(kls, region) != NULL) | |
2979 // A guard was added. If the guard is taken, it was an array. | |
2980 phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror()))); | |
2981 // If we fall through, it's a plain class. Get its _super. | |
2982 p = basic_plus_adr(kls, Klass::super_offset_in_bytes() + sizeof(oopDesc)); | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2983 kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL) ); |
0 | 2984 null_ctl = top(); |
2985 kls = null_check_oop(kls, &null_ctl); | |
2986 if (null_ctl != top()) { | |
2987 // If the guard is taken, Object.superClass is null (both klass and mirror). | |
2988 region->add_req(null_ctl); | |
2989 phi ->add_req(null()); | |
2990 } | |
2991 if (!stopped()) { | |
2992 query_value = load_mirror_from_klass(kls); | |
2993 } | |
2994 break; | |
2995 | |
2996 case vmIntrinsics::_getComponentType: | |
2997 if (generate_array_guard(kls, region) != NULL) { | |
2998 // Be sure to pin the oop load to the guard edge just created: | |
2999 Node* is_array_ctrl = region->in(region->req()-1); | |
3000 Node* cma = basic_plus_adr(kls, in_bytes(arrayKlass::component_mirror_offset()) + sizeof(oopDesc)); | |
3001 Node* cmo = make_load(is_array_ctrl, cma, TypeInstPtr::MIRROR, T_OBJECT); | |
3002 phi->add_req(cmo); | |
3003 } | |
3004 query_value = null(); // non-array case is null | |
3005 break; | |
3006 | |
3007 case vmIntrinsics::_getClassAccessFlags: | |
3008 p = basic_plus_adr(kls, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc)); | |
3009 query_value = make_load(NULL, p, TypeInt::INT, T_INT); | |
3010 break; | |
3011 | |
3012 default: | |
3013 ShouldNotReachHere(); | |
3014 } | |
3015 | |
3016 // Fall-through is the normal case of a query to a real class. | |
3017 phi->init_req(1, query_value); | |
3018 region->init_req(1, control()); | |
3019 | |
3020 push_result(region, phi); | |
3021 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
3022 | |
3023 return true; | |
3024 } | |
3025 | |
3026 //--------------------------inline_native_subtype_check------------------------ | |
3027 // This intrinsic takes the JNI calls out of the heart of | |
3028 // UnsafeFieldAccessorImpl.set, which improves Field.set, readObject, etc. | |
3029 bool LibraryCallKit::inline_native_subtype_check() { | |
3030 int nargs = 1+1; // the Class mirror, plus the other class getting examined | |
3031 | |
3032 // Pull both arguments off the stack. | |
3033 Node* args[2]; // two java.lang.Class mirrors: superc, subc | |
3034 args[0] = argument(0); | |
3035 args[1] = argument(1); | |
3036 Node* klasses[2]; // corresponding Klasses: superk, subk | |
3037 klasses[0] = klasses[1] = top(); | |
3038 | |
3039 enum { | |
3040 // A full decision tree on {superc is prim, subc is prim}: | |
3041 _prim_0_path = 1, // {P,N} => false | |
3042 // {P,P} & superc!=subc => false | |
3043 _prim_same_path, // {P,P} & superc==subc => true | |
3044 _prim_1_path, // {N,P} => false | |
3045 _ref_subtype_path, // {N,N} & subtype check wins => true | |
3046 _both_ref_path, // {N,N} & subtype check loses => false | |
3047 PATH_LIMIT | |
3048 }; | |
3049 | |
3050 RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
3051 Node* phi = new (C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL); | |
3052 record_for_igvn(region); | |
3053 | |
3054 const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads | |
3055 const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL; | |
3056 int class_klass_offset = java_lang_Class::klass_offset_in_bytes(); | |
3057 | |
3058 // First null-check both mirrors and load each mirror's klass metaobject. | |
3059 int which_arg; | |
3060 for (which_arg = 0; which_arg <= 1; which_arg++) { | |
3061 Node* arg = args[which_arg]; | |
3062 _sp += nargs; // set original stack for use by uncommon_trap | |
3063 arg = do_null_check(arg, T_OBJECT); | |
3064 _sp -= nargs; | |
3065 if (stopped()) break; | |
3066 args[which_arg] = _gvn.transform(arg); | |
3067 | |
3068 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
|
3069 Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type); |
0 | 3070 klasses[which_arg] = _gvn.transform(kls); |
3071 } | |
3072 | |
3073 // Having loaded both klasses, test each for null. | |
3074 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); | |
3075 for (which_arg = 0; which_arg <= 1; which_arg++) { | |
3076 Node* kls = klasses[which_arg]; | |
3077 Node* null_ctl = top(); | |
3078 _sp += nargs; // set original stack for use by uncommon_trap | |
3079 kls = null_check_oop(kls, &null_ctl, never_see_null); | |
3080 _sp -= nargs; | |
3081 int prim_path = (which_arg == 0 ? _prim_0_path : _prim_1_path); | |
3082 region->init_req(prim_path, null_ctl); | |
3083 if (stopped()) break; | |
3084 klasses[which_arg] = kls; | |
3085 } | |
3086 | |
3087 if (!stopped()) { | |
3088 // now we have two reference types, in klasses[0..1] | |
3089 Node* subk = klasses[1]; // the argument to isAssignableFrom | |
3090 Node* superk = klasses[0]; // the receiver | |
3091 region->set_req(_both_ref_path, gen_subtype_check(subk, superk)); | |
3092 // now we have a successful reference subtype check | |
3093 region->set_req(_ref_subtype_path, control()); | |
3094 } | |
3095 | |
3096 // If both operands are primitive (both klasses null), then | |
3097 // we must return true when they are identical primitives. | |
3098 // It is convenient to test this after the first null klass check. | |
3099 set_control(region->in(_prim_0_path)); // go back to first null check | |
3100 if (!stopped()) { | |
3101 // Since superc is primitive, make a guard for the superc==subc case. | |
3102 Node* cmp_eq = _gvn.transform( new (C, 3) CmpPNode(args[0], args[1]) ); | |
3103 Node* bol_eq = _gvn.transform( new (C, 2) BoolNode(cmp_eq, BoolTest::eq) ); | |
3104 generate_guard(bol_eq, region, PROB_FAIR); | |
3105 if (region->req() == PATH_LIMIT+1) { | |
3106 // A guard was added. If the added guard is taken, superc==subc. | |
3107 region->swap_edges(PATH_LIMIT, _prim_same_path); | |
3108 region->del_req(PATH_LIMIT); | |
3109 } | |
3110 region->set_req(_prim_0_path, control()); // Not equal after all. | |
3111 } | |
3112 | |
3113 // these are the only paths that produce 'true': | |
3114 phi->set_req(_prim_same_path, intcon(1)); | |
3115 phi->set_req(_ref_subtype_path, intcon(1)); | |
3116 | |
3117 // pull together the cases: | |
3118 assert(region->req() == PATH_LIMIT, "sane region"); | |
3119 for (uint i = 1; i < region->req(); i++) { | |
3120 Node* ctl = region->in(i); | |
3121 if (ctl == NULL || ctl == top()) { | |
3122 region->set_req(i, top()); | |
3123 phi ->set_req(i, top()); | |
3124 } else if (phi->in(i) == NULL) { | |
3125 phi->set_req(i, intcon(0)); // all other paths produce 'false' | |
3126 } | |
3127 } | |
3128 | |
3129 set_control(_gvn.transform(region)); | |
3130 push(_gvn.transform(phi)); | |
3131 | |
3132 return true; | |
3133 } | |
3134 | |
3135 //---------------------generate_array_guard_common------------------------ | |
3136 Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region, | |
3137 bool obj_array, bool not_array) { | |
3138 // If obj_array/non_array==false/false: | |
3139 // Branch around if the given klass is in fact an array (either obj or prim). | |
3140 // If obj_array/non_array==false/true: | |
3141 // Branch around if the given klass is not an array klass of any kind. | |
3142 // If obj_array/non_array==true/true: | |
3143 // Branch around if the kls is not an oop array (kls is int[], String, etc.) | |
3144 // If obj_array/non_array==true/false: | |
3145 // Branch around if the kls is an oop array (Object[] or subtype) | |
3146 // | |
3147 // Like generate_guard, adds a new path onto the region. | |
3148 jint layout_con = 0; | |
3149 Node* layout_val = get_layout_helper(kls, layout_con); | |
3150 if (layout_val == NULL) { | |
3151 bool query = (obj_array | |
3152 ? Klass::layout_helper_is_objArray(layout_con) | |
3153 : Klass::layout_helper_is_javaArray(layout_con)); | |
3154 if (query == not_array) { | |
3155 return NULL; // never a branch | |
3156 } else { // always a branch | |
3157 Node* always_branch = control(); | |
3158 if (region != NULL) | |
3159 region->add_req(always_branch); | |
3160 set_control(top()); | |
3161 return always_branch; | |
3162 } | |
3163 } | |
3164 // Now test the correct condition. | |
3165 jint nval = (obj_array | |
3166 ? ((jint)Klass::_lh_array_tag_type_value | |
3167 << Klass::_lh_array_tag_shift) | |
3168 : Klass::_lh_neutral_value); | |
3169 Node* cmp = _gvn.transform( new(C, 3) CmpINode(layout_val, intcon(nval)) ); | |
3170 BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array | |
3171 // invert the test if we are looking for a non-array | |
3172 if (not_array) btest = BoolTest(btest).negate(); | |
3173 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, btest) ); | |
3174 return generate_fair_guard(bol, region); | |
3175 } | |
3176 | |
3177 | |
3178 //-----------------------inline_native_newArray-------------------------- | |
3179 bool LibraryCallKit::inline_native_newArray() { | |
3180 int nargs = 2; | |
3181 Node* mirror = argument(0); | |
3182 Node* count_val = argument(1); | |
3183 | |
3184 _sp += nargs; // set original stack for use by uncommon_trap | |
3185 mirror = do_null_check(mirror, T_OBJECT); | |
3186 _sp -= nargs; | |
163 | 3187 // If mirror or obj is dead, only null-path is taken. |
3188 if (stopped()) return true; | |
0 | 3189 |
3190 enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT }; | |
3191 RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
3192 PhiNode* result_val = new(C, PATH_LIMIT) PhiNode(result_reg, | |
3193 TypeInstPtr::NOTNULL); | |
3194 PhiNode* result_io = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); | |
3195 PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, | |
3196 TypePtr::BOTTOM); | |
3197 | |
3198 bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); | |
3199 Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null, | |
3200 nargs, | |
3201 result_reg, _slow_path); | |
3202 Node* normal_ctl = control(); | |
3203 Node* no_array_ctl = result_reg->in(_slow_path); | |
3204 | |
3205 // Generate code for the slow case. We make a call to newArray(). | |
3206 set_control(no_array_ctl); | |
3207 if (!stopped()) { | |
3208 // Either the input type is void.class, or else the | |
3209 // array klass has not yet been cached. Either the | |
3210 // ensuing call will throw an exception, or else it | |
3211 // will cache the array klass for next time. | |
3212 PreserveJVMState pjvms(this); | |
3213 CallJavaNode* slow_call = generate_method_call_static(vmIntrinsics::_newArray); | |
3214 Node* slow_result = set_results_for_java_call(slow_call); | |
3215 // this->control() comes from set_results_for_java_call | |
3216 result_reg->set_req(_slow_path, control()); | |
3217 result_val->set_req(_slow_path, slow_result); | |
3218 result_io ->set_req(_slow_path, i_o()); | |
3219 result_mem->set_req(_slow_path, reset_memory()); | |
3220 } | |
3221 | |
3222 set_control(normal_ctl); | |
3223 if (!stopped()) { | |
3224 // Normal case: The array type has been cached in the java.lang.Class. | |
3225 // The following call works fine even if the array type is polymorphic. | |
3226 // It could be a dynamic mix of int[], boolean[], Object[], etc. | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
681
diff
changeset
|
3227 Node* obj = new_array(klass_node, count_val, nargs); |
0 | 3228 result_reg->init_req(_normal_path, control()); |
3229 result_val->init_req(_normal_path, obj); | |
3230 result_io ->init_req(_normal_path, i_o()); | |
3231 result_mem->init_req(_normal_path, reset_memory()); | |
3232 } | |
3233 | |
3234 // Return the combined state. | |
3235 set_i_o( _gvn.transform(result_io) ); | |
3236 set_all_memory( _gvn.transform(result_mem) ); | |
3237 push_result(result_reg, result_val); | |
3238 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
3239 | |
3240 return true; | |
3241 } | |
3242 | |
3243 //----------------------inline_native_getLength-------------------------- | |
3244 bool LibraryCallKit::inline_native_getLength() { | |
3245 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; | |
3246 | |
3247 int nargs = 1; | |
3248 Node* array = argument(0); | |
3249 | |
3250 _sp += nargs; // set original stack for use by uncommon_trap | |
3251 array = do_null_check(array, T_OBJECT); | |
3252 _sp -= nargs; | |
3253 | |
3254 // If array is dead, only null-path is taken. | |
3255 if (stopped()) return true; | |
3256 | |
3257 // Deoptimize if it is a non-array. | |
3258 Node* non_array = generate_non_array_guard(load_object_klass(array), NULL); | |
3259 | |
3260 if (non_array != NULL) { | |
3261 PreserveJVMState pjvms(this); | |
3262 set_control(non_array); | |
3263 _sp += nargs; // push the arguments back on the stack | |
3264 uncommon_trap(Deoptimization::Reason_intrinsic, | |
3265 Deoptimization::Action_maybe_recompile); | |
3266 } | |
3267 | |
3268 // If control is dead, only non-array-path is taken. | |
3269 if (stopped()) return true; | |
3270 | |
3271 // The works fine even if the array type is polymorphic. | |
3272 // It could be a dynamic mix of int[], boolean[], Object[], etc. | |
3273 push( load_array_length(array) ); | |
3274 | |
3275 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
3276 | |
3277 return true; | |
3278 } | |
3279 | |
3280 //------------------------inline_array_copyOf---------------------------- | |
3281 bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) { | |
3282 if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; | |
3283 | |
3284 // Restore the stack and pop off the arguments. | |
3285 int nargs = 3 + (is_copyOfRange? 1: 0); | |
3286 Node* original = argument(0); | |
3287 Node* start = is_copyOfRange? argument(1): intcon(0); | |
3288 Node* end = is_copyOfRange? argument(2): argument(1); | |
3289 Node* array_type_mirror = is_copyOfRange? argument(3): argument(2); | |
3290 | |
902
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3291 Node* newcopy; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3292 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3293 //set the original stack and the reexecute bit for the interpreter to reexecute |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3294 //the bytecode that invokes Arrays.copyOf if deoptimization happens |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3295 { PreserveReexecuteState preexecs(this); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3296 _sp += nargs; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3297 jvms()->set_should_reexecute(true); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3298 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3299 array_type_mirror = do_null_check(array_type_mirror, T_OBJECT); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3300 original = do_null_check(original, T_OBJECT); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3301 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3302 // Check if a null path was taken unconditionally. |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3303 if (stopped()) return true; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3304 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3305 Node* orig_length = load_array_length(original); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3306 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3307 Node* klass_node = load_klass_from_mirror(array_type_mirror, false, 0, |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3308 NULL, 0); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3309 klass_node = do_null_check(klass_node, T_OBJECT); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3310 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3311 RegionNode* bailout = new (C, 1) RegionNode(1); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3312 record_for_igvn(bailout); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3313 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3314 // 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
|
3315 // Bail out if that is so. |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3316 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
|
3317 if (not_objArray != NULL) { |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3318 // 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
|
3319 ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3320 const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3321 Node* cast = new (C, 2) CastPPNode(klass_node, akls); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3322 cast->init_req(0, control()); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3323 klass_node = _gvn.transform(cast); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3324 } |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3325 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3326 // 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
|
3327 generate_negative_guard(start, bailout, &start); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3328 generate_negative_guard(end, bailout, &end); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3329 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3330 Node* length = end; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3331 if (_gvn.type(start) != TypeInt::ZERO) { |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3332 length = _gvn.transform( new (C, 3) SubINode(end, start) ); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3333 } |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3334 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3335 // Bail out if length is negative. |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3336 // ...Not needed, since the new_array will throw the right exception. |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3337 //generate_negative_guard(length, bailout, &length); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3338 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3339 if (bailout->req() > 1) { |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3340 PreserveJVMState pjvms(this); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3341 set_control( _gvn.transform(bailout) ); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3342 uncommon_trap(Deoptimization::Reason_intrinsic, |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3343 Deoptimization::Action_maybe_recompile); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3344 } |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3345 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3346 if (!stopped()) { |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3347 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3348 // 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
|
3349 // The answer is MinI(orig_length - start, length). |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3350 Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3351 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
|
3352 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3353 const bool raw_mem_only = true; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3354 newcopy = new_array(klass_node, length, 0, raw_mem_only); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3355 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3356 // 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
|
3357 // 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
|
3358 // oop stores need checking. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3359 // 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
|
3360 // 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
|
3361 bool disjoint_bases = true; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3362 bool length_never_negative = true; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3363 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3364 original, start, newcopy, intcon(0), moved, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
3365 disjoint_bases, length_never_negative); |
902
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3366 } |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3367 } //original reexecute and sp are set back here |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3368 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
3369 if(!stopped()) { |
0 | 3370 push(newcopy); |
3371 } | |
3372 | |
3373 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
3374 | |
3375 return true; | |
3376 } | |
3377 | |
3378 | |
3379 //----------------------generate_virtual_guard--------------------------- | |
3380 // Helper for hashCode and clone. Peeks inside the vtable to avoid a call. | |
3381 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass, | |
3382 RegionNode* slow_region) { | |
3383 ciMethod* method = callee(); | |
3384 int vtable_index = method->vtable_index(); | |
3385 // Get the methodOop out of the appropriate vtable entry. | |
3386 int entry_offset = (instanceKlass::vtable_start_offset() + | |
3387 vtable_index*vtableEntry::size()) * wordSize + | |
3388 vtableEntry::method_offset_in_bytes(); | |
3389 Node* entry_addr = basic_plus_adr(obj_klass, entry_offset); | |
3390 Node* target_call = make_load(NULL, entry_addr, TypeInstPtr::NOTNULL, T_OBJECT); | |
3391 | |
3392 // Compare the target method with the expected method (e.g., Object.hashCode). | |
3393 const TypeInstPtr* native_call_addr = TypeInstPtr::make(method); | |
3394 | |
3395 Node* native_call = makecon(native_call_addr); | |
3396 Node* chk_native = _gvn.transform( new(C, 3) CmpPNode(target_call, native_call) ); | |
3397 Node* test_native = _gvn.transform( new(C, 2) BoolNode(chk_native, BoolTest::ne) ); | |
3398 | |
3399 return generate_slow_guard(test_native, slow_region); | |
3400 } | |
3401 | |
3402 //-----------------------generate_method_call---------------------------- | |
3403 // Use generate_method_call to make a slow-call to the real | |
3404 // method if the fast path fails. An alternative would be to | |
3405 // use a stub like OptoRuntime::slow_arraycopy_Java. | |
3406 // This only works for expanding the current library call, | |
3407 // not another intrinsic. (E.g., don't use this for making an | |
3408 // arraycopy call inside of the copyOf intrinsic.) | |
3409 CallJavaNode* | |
3410 LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual, bool is_static) { | |
3411 // When compiling the intrinsic method itself, do not use this technique. | |
3412 guarantee(callee() != C->method(), "cannot make slow-call to self"); | |
3413 | |
3414 ciMethod* method = callee(); | |
3415 // ensure the JVMS we have will be correct for this call | |
3416 guarantee(method_id == method->intrinsic_id(), "must match"); | |
3417 | |
3418 const TypeFunc* tf = TypeFunc::make(method); | |
3419 int tfdc = tf->domain()->cnt(); | |
3420 CallJavaNode* slow_call; | |
3421 if (is_static) { | |
3422 assert(!is_virtual, ""); | |
3423 slow_call = new(C, tfdc) CallStaticJavaNode(tf, | |
3424 SharedRuntime::get_resolve_static_call_stub(), | |
3425 method, bci()); | |
3426 } else if (is_virtual) { | |
3427 null_check_receiver(method); | |
3428 int vtable_index = methodOopDesc::invalid_vtable_index; | |
3429 if (UseInlineCaches) { | |
3430 // Suppress the vtable call | |
3431 } else { | |
3432 // hashCode and clone are not a miranda methods, | |
3433 // so the vtable index is fixed. | |
3434 // No need to use the linkResolver to get it. | |
3435 vtable_index = method->vtable_index(); | |
3436 } | |
3437 slow_call = new(C, tfdc) CallDynamicJavaNode(tf, | |
3438 SharedRuntime::get_resolve_virtual_call_stub(), | |
3439 method, vtable_index, bci()); | |
3440 } else { // neither virtual nor static: opt_virtual | |
3441 null_check_receiver(method); | |
3442 slow_call = new(C, tfdc) CallStaticJavaNode(tf, | |
3443 SharedRuntime::get_resolve_opt_virtual_call_stub(), | |
3444 method, bci()); | |
3445 slow_call->set_optimized_virtual(true); | |
3446 } | |
3447 set_arguments_for_java_call(slow_call); | |
3448 set_edges_for_java_call(slow_call); | |
3449 return slow_call; | |
3450 } | |
3451 | |
3452 | |
3453 //------------------------------inline_native_hashcode-------------------- | |
3454 // Build special case code for calls to hashCode on an object. | |
3455 bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { | |
3456 assert(is_static == callee()->is_static(), "correct intrinsic selection"); | |
3457 assert(!(is_virtual && is_static), "either virtual, special, or static"); | |
3458 | |
3459 enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT }; | |
3460 | |
3461 RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
3462 PhiNode* result_val = new(C, PATH_LIMIT) PhiNode(result_reg, | |
3463 TypeInt::INT); | |
3464 PhiNode* result_io = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); | |
3465 PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, | |
3466 TypePtr::BOTTOM); | |
3467 Node* obj = NULL; | |
3468 if (!is_static) { | |
3469 // Check for hashing null object | |
3470 obj = null_check_receiver(callee()); | |
3471 if (stopped()) return true; // unconditionally null | |
3472 result_reg->init_req(_null_path, top()); | |
3473 result_val->init_req(_null_path, top()); | |
3474 } else { | |
3475 // Do a null check, and return zero if null. | |
3476 // System.identityHashCode(null) == 0 | |
3477 obj = argument(0); | |
3478 Node* null_ctl = top(); | |
3479 obj = null_check_oop(obj, &null_ctl); | |
3480 result_reg->init_req(_null_path, null_ctl); | |
3481 result_val->init_req(_null_path, _gvn.intcon(0)); | |
3482 } | |
3483 | |
3484 // Unconditionally null? Then return right away. | |
3485 if (stopped()) { | |
3486 set_control( result_reg->in(_null_path) ); | |
3487 if (!stopped()) | |
3488 push( result_val ->in(_null_path) ); | |
3489 return true; | |
3490 } | |
3491 | |
3492 // After null check, get the object's klass. | |
3493 Node* obj_klass = load_object_klass(obj); | |
3494 | |
3495 // This call may be virtual (invokevirtual) or bound (invokespecial). | |
3496 // For each case we generate slightly different code. | |
3497 | |
3498 // We only go to the fast case code if we pass a number of guards. The | |
3499 // paths which do not pass are accumulated in the slow_region. | |
3500 RegionNode* slow_region = new (C, 1) RegionNode(1); | |
3501 record_for_igvn(slow_region); | |
3502 | |
3503 // If this is a virtual call, we generate a funny guard. We pull out | |
3504 // the vtable entry corresponding to hashCode() from the target object. | |
3505 // If the target method which we are calling happens to be the native | |
3506 // Object hashCode() method, we pass the guard. We do not need this | |
3507 // guard for non-virtual calls -- the caller is known to be the native | |
3508 // Object hashCode(). | |
3509 if (is_virtual) { | |
3510 generate_virtual_guard(obj_klass, slow_region); | |
3511 } | |
3512 | |
3513 // Get the header out of the object, use LoadMarkNode when available | |
3514 Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); | |
1609 | 3515 Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type()); |
0 | 3516 |
3517 // Test the header to see if it is unlocked. | |
3518 Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); | |
3519 Node *lmasked_header = _gvn.transform( new (C, 3) AndXNode(header, lock_mask) ); | |
3520 Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); | |
3521 Node *chk_unlocked = _gvn.transform( new (C, 3) CmpXNode( lmasked_header, unlocked_val)); | |
3522 Node *test_unlocked = _gvn.transform( new (C, 2) BoolNode( chk_unlocked, BoolTest::ne) ); | |
3523 | |
3524 generate_slow_guard(test_unlocked, slow_region); | |
3525 | |
3526 // Get the hash value and check to see that it has been properly assigned. | |
3527 // We depend on hash_mask being at most 32 bits and avoid the use of | |
3528 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit | |
3529 // vm: see markOop.hpp. | |
3530 Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); | |
3531 Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); | |
3532 Node *hshifted_header= _gvn.transform( new (C, 3) URShiftXNode(header, hash_shift) ); | |
3533 // This hack lets the hash bits live anywhere in the mark object now, as long | |
605 | 3534 // as the shift drops the relevant bits into the low 32 bits. Note that |
0 | 3535 // Java spec says that HashCode is an int so there's no point in capturing |
3536 // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). | |
3537 hshifted_header = ConvX2I(hshifted_header); | |
3538 Node *hash_val = _gvn.transform( new (C, 3) AndINode(hshifted_header, hash_mask) ); | |
3539 | |
3540 Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); | |
3541 Node *chk_assigned = _gvn.transform( new (C, 3) CmpINode( hash_val, no_hash_val)); | |
3542 Node *test_assigned = _gvn.transform( new (C, 2) BoolNode( chk_assigned, BoolTest::eq) ); | |
3543 | |
3544 generate_slow_guard(test_assigned, slow_region); | |
3545 | |
3546 Node* init_mem = reset_memory(); | |
3547 // fill in the rest of the null path: | |
3548 result_io ->init_req(_null_path, i_o()); | |
3549 result_mem->init_req(_null_path, init_mem); | |
3550 | |
3551 result_val->init_req(_fast_path, hash_val); | |
3552 result_reg->init_req(_fast_path, control()); | |
3553 result_io ->init_req(_fast_path, i_o()); | |
3554 result_mem->init_req(_fast_path, init_mem); | |
3555 | |
3556 // Generate code for the slow case. We make a call to hashCode(). | |
3557 set_control(_gvn.transform(slow_region)); | |
3558 if (!stopped()) { | |
3559 // No need for PreserveJVMState, because we're using up the present state. | |
3560 set_all_memory(init_mem); | |
3561 vmIntrinsics::ID hashCode_id = vmIntrinsics::_hashCode; | |
3562 if (is_static) hashCode_id = vmIntrinsics::_identityHashCode; | |
3563 CallJavaNode* slow_call = generate_method_call(hashCode_id, is_virtual, is_static); | |
3564 Node* slow_result = set_results_for_java_call(slow_call); | |
3565 // this->control() comes from set_results_for_java_call | |
3566 result_reg->init_req(_slow_path, control()); | |
3567 result_val->init_req(_slow_path, slow_result); | |
3568 result_io ->set_req(_slow_path, i_o()); | |
3569 result_mem ->set_req(_slow_path, reset_memory()); | |
3570 } | |
3571 | |
3572 // Return the combined state. | |
3573 set_i_o( _gvn.transform(result_io) ); | |
3574 set_all_memory( _gvn.transform(result_mem) ); | |
3575 push_result(result_reg, result_val); | |
3576 | |
3577 return true; | |
3578 } | |
3579 | |
3580 //---------------------------inline_native_getClass---------------------------- | |
605 | 3581 // Build special case code for calls to getClass on an object. |
0 | 3582 bool LibraryCallKit::inline_native_getClass() { |
3583 Node* obj = null_check_receiver(callee()); | |
3584 if (stopped()) return true; | |
3585 push( load_mirror_from_klass(load_object_klass(obj)) ); | |
3586 return true; | |
3587 } | |
3588 | |
3589 //-----------------inline_native_Reflection_getCallerClass--------------------- | |
3590 // In the presence of deep enough inlining, getCallerClass() becomes a no-op. | |
3591 // | |
3592 // NOTE that this code must perform the same logic as | |
3593 // vframeStream::security_get_caller_frame in that it must skip | |
3594 // Method.invoke() and auxiliary frames. | |
3595 | |
3596 | |
3597 | |
3598 | |
3599 bool LibraryCallKit::inline_native_Reflection_getCallerClass() { | |
3600 ciMethod* method = callee(); | |
3601 | |
3602 #ifndef PRODUCT | |
3603 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | |
3604 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); | |
3605 } | |
3606 #endif | |
3607 | |
3608 debug_only(int saved_sp = _sp); | |
3609 | |
3610 // Argument words: (int depth) | |
3611 int nargs = 1; | |
3612 | |
3613 _sp += nargs; | |
3614 Node* caller_depth_node = pop(); | |
3615 | |
3616 assert(saved_sp == _sp, "must have correct argument count"); | |
3617 | |
3618 // The depth value must be a constant in order for the runtime call | |
3619 // to be eliminated. | |
3620 const TypeInt* caller_depth_type = _gvn.type(caller_depth_node)->isa_int(); | |
3621 if (caller_depth_type == NULL || !caller_depth_type->is_con()) { | |
3622 #ifndef PRODUCT | |
3623 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | |
3624 tty->print_cr(" Bailing out because caller depth was not a constant"); | |
3625 } | |
3626 #endif | |
3627 return false; | |
3628 } | |
3629 // Note that the JVM state at this point does not include the | |
3630 // getCallerClass() frame which we are trying to inline. The | |
3631 // semantics of getCallerClass(), however, are that the "first" | |
3632 // frame is the getCallerClass() frame, so we subtract one from the | |
3633 // requested depth before continuing. We don't inline requests of | |
3634 // getCallerClass(0). | |
3635 int caller_depth = caller_depth_type->get_con() - 1; | |
3636 if (caller_depth < 0) { | |
3637 #ifndef PRODUCT | |
3638 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | |
3639 tty->print_cr(" Bailing out because caller depth was %d", caller_depth); | |
3640 } | |
3641 #endif | |
3642 return false; | |
3643 } | |
3644 | |
3645 if (!jvms()->has_method()) { | |
3646 #ifndef PRODUCT | |
3647 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | |
3648 tty->print_cr(" Bailing out because intrinsic was inlined at top level"); | |
3649 } | |
3650 #endif | |
3651 return false; | |
3652 } | |
3653 int _depth = jvms()->depth(); // cache call chain depth | |
3654 | |
3655 // Walk back up the JVM state to find the caller at the required | |
3656 // depth. NOTE that this code must perform the same logic as | |
3657 // vframeStream::security_get_caller_frame in that it must skip | |
3658 // Method.invoke() and auxiliary frames. Note also that depth is | |
3659 // 1-based (1 is the bottom of the inlining). | |
3660 int inlining_depth = _depth; | |
3661 JVMState* caller_jvms = NULL; | |
3662 | |
3663 if (inlining_depth > 0) { | |
3664 caller_jvms = jvms(); | |
3665 assert(caller_jvms = jvms()->of_depth(inlining_depth), "inlining_depth == our depth"); | |
3666 do { | |
3667 // The following if-tests should be performed in this order | |
3668 if (is_method_invoke_or_aux_frame(caller_jvms)) { | |
3669 // Skip a Method.invoke() or auxiliary frame | |
3670 } else if (caller_depth > 0) { | |
3671 // Skip real frame | |
3672 --caller_depth; | |
3673 } else { | |
3674 // We're done: reached desired caller after skipping. | |
3675 break; | |
3676 } | |
3677 caller_jvms = caller_jvms->caller(); | |
3678 --inlining_depth; | |
3679 } while (inlining_depth > 0); | |
3680 } | |
3681 | |
3682 if (inlining_depth == 0) { | |
3683 #ifndef PRODUCT | |
3684 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | |
3685 tty->print_cr(" Bailing out because caller depth (%d) exceeded inlining depth (%d)", caller_depth_type->get_con(), _depth); | |
3686 tty->print_cr(" JVM state at this point:"); | |
3687 for (int i = _depth; i >= 1; i--) { | |
3688 tty->print_cr(" %d) %s", i, jvms()->of_depth(i)->method()->name()->as_utf8()); | |
3689 } | |
3690 } | |
3691 #endif | |
3692 return false; // Reached end of inlining | |
3693 } | |
3694 | |
3695 // Acquire method holder as java.lang.Class | |
3696 ciInstanceKlass* caller_klass = caller_jvms->method()->holder(); | |
3697 ciInstance* caller_mirror = caller_klass->java_mirror(); | |
3698 // Push this as a constant | |
3699 push(makecon(TypeInstPtr::make(caller_mirror))); | |
3700 #ifndef PRODUCT | |
3701 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | |
3702 tty->print_cr(" Succeeded: caller = %s.%s, caller depth = %d, depth = %d", caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), caller_depth_type->get_con(), _depth); | |
3703 tty->print_cr(" JVM state at this point:"); | |
3704 for (int i = _depth; i >= 1; i--) { | |
3705 tty->print_cr(" %d) %s", i, jvms()->of_depth(i)->method()->name()->as_utf8()); | |
3706 } | |
3707 } | |
3708 #endif | |
3709 return true; | |
3710 } | |
3711 | |
3712 // Helper routine for above | |
3713 bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) { | |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3714 ciMethod* method = jvms->method(); |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3715 |
0 | 3716 // Is this the Method.invoke method itself? |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3717 if (method->intrinsic_id() == vmIntrinsics::_invoke) |
0 | 3718 return true; |
3719 | |
3720 // Is this a helper, defined somewhere underneath MethodAccessorImpl. | |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3721 ciKlass* k = method->holder(); |
0 | 3722 if (k->is_instance_klass()) { |
3723 ciInstanceKlass* ik = k->as_instance_klass(); | |
3724 for (; ik != NULL; ik = ik->super()) { | |
3725 if (ik->name() == ciSymbol::sun_reflect_MethodAccessorImpl() && | |
3726 ik == env()->find_system_klass(ik->name())) { | |
3727 return true; | |
3728 } | |
3729 } | |
3730 } | |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3731 else if (method->is_method_handle_adapter()) { |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3732 // This is an internal adapter frame from the MethodHandleCompiler -- skip it |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3733 return true; |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1027
diff
changeset
|
3734 } |
0 | 3735 |
3736 return false; | |
3737 } | |
3738 | |
3739 static int value_field_offset = -1; // offset of the "value" field of AtomicLongCSImpl. This is needed by | |
3740 // inline_native_AtomicLong_attemptUpdate() but it has no way of | |
3741 // computing it since there is no lookup field by name function in the | |
3742 // CI interface. This is computed and set by inline_native_AtomicLong_get(). | |
3743 // Using a static variable here is safe even if we have multiple compilation | |
3744 // threads because the offset is constant. At worst the same offset will be | |
3745 // computed and stored multiple | |
3746 | |
3747 bool LibraryCallKit::inline_native_AtomicLong_get() { | |
3748 // Restore the stack and pop off the argument | |
3749 _sp+=1; | |
3750 Node *obj = pop(); | |
3751 | |
3752 // get the offset of the "value" field. Since the CI interfaces | |
3753 // does not provide a way to look up a field by name, we scan the bytecodes | |
3754 // to get the field index. We expect the first 2 instructions of the method | |
3755 // to be: | |
3756 // 0 aload_0 | |
3757 // 1 getfield "value" | |
3758 ciMethod* method = callee(); | |
3759 if (value_field_offset == -1) | |
3760 { | |
3761 ciField* value_field; | |
3762 ciBytecodeStream iter(method); | |
3763 Bytecodes::Code bc = iter.next(); | |
3764 | |
3765 if ((bc != Bytecodes::_aload_0) && | |
3766 ((bc != Bytecodes::_aload) || (iter.get_index() != 0))) | |
3767 return false; | |
3768 bc = iter.next(); | |
3769 if (bc != Bytecodes::_getfield) | |
3770 return false; | |
3771 bool ignore; | |
3772 value_field = iter.get_field(ignore); | |
3773 value_field_offset = value_field->offset_in_bytes(); | |
3774 } | |
3775 | |
3776 // Null check without removing any arguments. | |
3777 _sp++; | |
3778 obj = do_null_check(obj, T_OBJECT); | |
3779 _sp--; | |
3780 // Check for locking null object | |
3781 if (stopped()) return true; | |
3782 | |
3783 Node *adr = basic_plus_adr(obj, obj, value_field_offset); | |
3784 const TypePtr *adr_type = _gvn.type(adr)->is_ptr(); | |
3785 int alias_idx = C->get_alias_index(adr_type); | |
3786 | |
3787 Node *result = _gvn.transform(new (C, 3) LoadLLockedNode(control(), memory(alias_idx), adr)); | |
3788 | |
3789 push_pair(result); | |
3790 | |
3791 return true; | |
3792 } | |
3793 | |
3794 bool LibraryCallKit::inline_native_AtomicLong_attemptUpdate() { | |
3795 // Restore the stack and pop off the arguments | |
3796 _sp+=5; | |
3797 Node *newVal = pop_pair(); | |
3798 Node *oldVal = pop_pair(); | |
3799 Node *obj = pop(); | |
3800 | |
3801 // we need the offset of the "value" field which was computed when | |
3802 // inlining the get() method. Give up if we don't have it. | |
3803 if (value_field_offset == -1) | |
3804 return false; | |
3805 | |
3806 // Null check without removing any arguments. | |
3807 _sp+=5; | |
3808 obj = do_null_check(obj, T_OBJECT); | |
3809 _sp-=5; | |
3810 // Check for locking null object | |
3811 if (stopped()) return true; | |
3812 | |
3813 Node *adr = basic_plus_adr(obj, obj, value_field_offset); | |
3814 const TypePtr *adr_type = _gvn.type(adr)->is_ptr(); | |
3815 int alias_idx = C->get_alias_index(adr_type); | |
3816 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3817 Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal)); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3818 Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas)); |
0 | 3819 set_memory(store_proj, alias_idx); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3820 Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) ); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3821 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3822 Node *result; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3823 // CMove node is not used to be able fold a possible check code |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3824 // after attemptUpdate() call. This code could be transformed |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3825 // into CMove node by loop optimizations. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3826 { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3827 RegionNode *r = new (C, 3) RegionNode(3); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3828 result = new (C, 3) PhiNode(r, TypeInt::BOOL); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3829 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3830 Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3831 Node *iftrue = opt_iff(r, iff); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3832 r->init_req(1, iftrue); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3833 result->init_req(1, intcon(1)); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3834 result->init_req(2, intcon(0)); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3835 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3836 set_control(_gvn.transform(r)); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3837 record_for_igvn(r); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3838 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3839 C->set_has_split_ifs(true); // Has chance for split-if optimization |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3840 } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3841 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
235
diff
changeset
|
3842 push(_gvn.transform(result)); |
0 | 3843 return true; |
3844 } | |
3845 | |
3846 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) { | |
3847 // restore the arguments | |
3848 _sp += arg_size(); | |
3849 | |
3850 switch (id) { | |
3851 case vmIntrinsics::_floatToRawIntBits: | |
3852 push(_gvn.transform( new (C, 2) MoveF2INode(pop()))); | |
3853 break; | |
3854 | |
3855 case vmIntrinsics::_intBitsToFloat: | |
3856 push(_gvn.transform( new (C, 2) MoveI2FNode(pop()))); | |
3857 break; | |
3858 | |
3859 case vmIntrinsics::_doubleToRawLongBits: | |
3860 push_pair(_gvn.transform( new (C, 2) MoveD2LNode(pop_pair()))); | |
3861 break; | |
3862 | |
3863 case vmIntrinsics::_longBitsToDouble: | |
3864 push_pair(_gvn.transform( new (C, 2) MoveL2DNode(pop_pair()))); | |
3865 break; | |
3866 | |
3867 case vmIntrinsics::_doubleToLongBits: { | |
3868 Node* value = pop_pair(); | |
3869 | |
3870 // two paths (plus control) merge in a wood | |
3871 RegionNode *r = new (C, 3) RegionNode(3); | |
3872 Node *phi = new (C, 3) PhiNode(r, TypeLong::LONG); | |
3873 | |
3874 Node *cmpisnan = _gvn.transform( new (C, 3) CmpDNode(value, value)); | |
3875 // Build the boolean node | |
3876 Node *bolisnan = _gvn.transform( new (C, 2) BoolNode( cmpisnan, BoolTest::ne ) ); | |
3877 | |
3878 // Branch either way. | |
3879 // NaN case is less traveled, which makes all the difference. | |
3880 IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); | |
3881 Node *opt_isnan = _gvn.transform(ifisnan); | |
3882 assert( opt_isnan->is_If(), "Expect an IfNode"); | |
3883 IfNode *opt_ifisnan = (IfNode*)opt_isnan; | |
3884 Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(opt_ifisnan) ); | |
3885 | |
3886 set_control(iftrue); | |
3887 | |
3888 static const jlong nan_bits = CONST64(0x7ff8000000000000); | |
3889 Node *slow_result = longcon(nan_bits); // return NaN | |
3890 phi->init_req(1, _gvn.transform( slow_result )); | |
3891 r->init_req(1, iftrue); | |
3892 | |
3893 // Else fall through | |
3894 Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(opt_ifisnan) ); | |
3895 set_control(iffalse); | |
3896 | |
3897 phi->init_req(2, _gvn.transform( new (C, 2) MoveD2LNode(value))); | |
3898 r->init_req(2, iffalse); | |
3899 | |
3900 // Post merge | |
3901 set_control(_gvn.transform(r)); | |
3902 record_for_igvn(r); | |
3903 | |
3904 Node* result = _gvn.transform(phi); | |
3905 assert(result->bottom_type()->isa_long(), "must be"); | |
3906 push_pair(result); | |
3907 | |
3908 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
3909 | |
3910 break; | |
3911 } | |
3912 | |
3913 case vmIntrinsics::_floatToIntBits: { | |
3914 Node* value = pop(); | |
3915 | |
3916 // two paths (plus control) merge in a wood | |
3917 RegionNode *r = new (C, 3) RegionNode(3); | |
3918 Node *phi = new (C, 3) PhiNode(r, TypeInt::INT); | |
3919 | |
3920 Node *cmpisnan = _gvn.transform( new (C, 3) CmpFNode(value, value)); | |
3921 // Build the boolean node | |
3922 Node *bolisnan = _gvn.transform( new (C, 2) BoolNode( cmpisnan, BoolTest::ne ) ); | |
3923 | |
3924 // Branch either way. | |
3925 // NaN case is less traveled, which makes all the difference. | |
3926 IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); | |
3927 Node *opt_isnan = _gvn.transform(ifisnan); | |
3928 assert( opt_isnan->is_If(), "Expect an IfNode"); | |
3929 IfNode *opt_ifisnan = (IfNode*)opt_isnan; | |
3930 Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(opt_ifisnan) ); | |
3931 | |
3932 set_control(iftrue); | |
3933 | |
3934 static const jint nan_bits = 0x7fc00000; | |
3935 Node *slow_result = makecon(TypeInt::make(nan_bits)); // return NaN | |
3936 phi->init_req(1, _gvn.transform( slow_result )); | |
3937 r->init_req(1, iftrue); | |
3938 | |
3939 // Else fall through | |
3940 Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(opt_ifisnan) ); | |
3941 set_control(iffalse); | |
3942 | |
3943 phi->init_req(2, _gvn.transform( new (C, 2) MoveF2INode(value))); | |
3944 r->init_req(2, iffalse); | |
3945 | |
3946 // Post merge | |
3947 set_control(_gvn.transform(r)); | |
3948 record_for_igvn(r); | |
3949 | |
3950 Node* result = _gvn.transform(phi); | |
3951 assert(result->bottom_type()->isa_int(), "must be"); | |
3952 push(result); | |
3953 | |
3954 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
3955 | |
3956 break; | |
3957 } | |
3958 | |
3959 default: | |
3960 ShouldNotReachHere(); | |
3961 } | |
3962 | |
3963 return true; | |
3964 } | |
3965 | |
3966 #ifdef _LP64 | |
3967 #define XTOP ,top() /*additional argument*/ | |
3968 #else //_LP64 | |
3969 #define XTOP /*no additional argument*/ | |
3970 #endif //_LP64 | |
3971 | |
3972 //----------------------inline_unsafe_copyMemory------------------------- | |
3973 bool LibraryCallKit::inline_unsafe_copyMemory() { | |
3974 if (callee()->is_static()) return false; // caller must have the capability! | |
3975 int nargs = 1 + 5 + 3; // 5 args: (src: ptr,off, dst: ptr,off, size) | |
3976 assert(signature()->size() == nargs-1, "copy has 5 arguments"); | |
3977 null_check_receiver(callee()); // check then ignore argument(0) | |
3978 if (stopped()) return true; | |
3979 | |
3980 C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". | |
3981 | |
3982 Node* src_ptr = argument(1); | |
3983 Node* src_off = ConvL2X(argument(2)); | |
3984 assert(argument(3)->is_top(), "2nd half of long"); | |
3985 Node* dst_ptr = argument(4); | |
3986 Node* dst_off = ConvL2X(argument(5)); | |
3987 assert(argument(6)->is_top(), "2nd half of long"); | |
3988 Node* size = ConvL2X(argument(7)); | |
3989 assert(argument(8)->is_top(), "2nd half of long"); | |
3990 | |
3991 assert(Unsafe_field_offset_to_byte_offset(11) == 11, | |
3992 "fieldOffset must be byte-scaled"); | |
3993 | |
3994 Node* src = make_unsafe_address(src_ptr, src_off); | |
3995 Node* dst = make_unsafe_address(dst_ptr, dst_off); | |
3996 | |
3997 // Conservatively insert a memory barrier on all memory slices. | |
3998 // Do not let writes of the copy source or destination float below the copy. | |
3999 insert_mem_bar(Op_MemBarCPUOrder); | |
4000 | |
4001 // Call it. Note that the length argument is not scaled. | |
4002 make_runtime_call(RC_LEAF|RC_NO_FP, | |
4003 OptoRuntime::fast_arraycopy_Type(), | |
4004 StubRoutines::unsafe_arraycopy(), | |
4005 "unsafe_arraycopy", | |
4006 TypeRawPtr::BOTTOM, | |
4007 src, dst, size XTOP); | |
4008 | |
4009 // Do not let reads of the copy destination float above the copy. | |
4010 insert_mem_bar(Op_MemBarCPUOrder); | |
4011 | |
4012 return true; | |
4013 } | |
4014 | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4015 //------------------------clone_coping----------------------------------- |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4016 // 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
|
4017 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
|
4018 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
|
4019 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
|
4020 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
|
4021 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4022 if (ReduceBulkZeroing) { |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4023 // 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
|
4024 // mark Initialize node as complete. |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4025 AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4026 // 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
|
4027 guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), ""); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4028 } |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4029 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4030 // 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
|
4031 // 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
|
4032 Node* src = obj; |
958
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4033 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
|
4034 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
|
4035 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4036 // 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
|
4037 // 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
|
4038 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
|
4039 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
|
4040 // base_off: |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4041 // 8 - 32-bit VM |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4042 // 12 - 64-bit VM, compressed oops |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4043 // 16 - 64-bit VM, normal oops |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4044 if (base_off % BytesPerLong != 0) { |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4045 assert(UseCompressedOops, ""); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4046 if (is_array) { |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4047 // 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
|
4048 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
|
4049 } else { |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4050 // 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
|
4051 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
|
4052 } |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4053 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
|
4054 } |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4055 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
|
4056 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
|
4057 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4058 // 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
|
4059 Node* countx = size; |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4060 countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) ); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4061 countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) )); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4062 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4063 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
|
4064 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
|
4065 generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4066 src, NULL, dest, NULL, countx); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4067 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4068 // 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
|
4069 if (card_mark) { |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4070 assert(!is_array, ""); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4071 // 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
|
4072 // 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
|
4073 // 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
|
4074 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
|
4075 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
|
4076 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
|
4077 post_barrier(control(), |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4078 memory(raw_adr_type), |
958
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4079 alloc_obj, |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4080 no_particular_field, |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4081 raw_adr_idx, |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4082 no_particular_value, |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4083 T_OBJECT, |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4084 false); |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4085 } |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4086 |
958
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4087 // Do not let reads from the cloned object float above the arraycopy. |
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4088 insert_mem_bar(Op_MemBarCPUOrder); |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4089 } |
0 | 4090 |
4091 //------------------------inline_native_clone---------------------------- | |
4092 // Here are the simple edge cases: | |
4093 // null receiver => normal trap | |
4094 // virtual and clone was overridden => slow path to out-of-line clone | |
4095 // not cloneable or finalizer => slow path to out-of-line Object.clone | |
4096 // | |
4097 // The general case has two steps, allocation and copying. | |
4098 // Allocation has two cases, and uses GraphKit::new_instance or new_array. | |
4099 // | |
4100 // Copying also has two cases, oop arrays and everything else. | |
4101 // Oop arrays use arrayof_oop_arraycopy (same as System.arraycopy). | |
4102 // Everything else uses the tight inline loop supplied by CopyArrayNode. | |
4103 // | |
4104 // These steps fold up nicely if and when the cloned object's klass | |
4105 // can be sharply typed as an object array, a type array, or an instance. | |
4106 // | |
4107 bool LibraryCallKit::inline_native_clone(bool is_virtual) { | |
4108 int nargs = 1; | |
902
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4109 PhiNode* result_val; |
0 | 4110 |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4111 //set the original stack and the reexecute bit for the interpreter to reexecute |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4112 //the bytecode that invokes Object.clone if deoptimization happens |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4113 { PreserveReexecuteState preexecs(this); |
902
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4114 jvms()->set_should_reexecute(true); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4115 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4116 //null_check_receiver will adjust _sp (push and pop) |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4117 Node* obj = null_check_receiver(callee()); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4118 if (stopped()) return true; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4119 |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4120 _sp += nargs; |
902
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4121 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4122 Node* obj_klass = load_object_klass(obj); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4123 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
|
4124 const TypeOopPtr* toop = ((tklass != NULL) |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4125 ? tklass->as_instance_type() |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4126 : TypeInstPtr::NOTNULL); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4127 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4128 // 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
|
4129 // 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
|
4130 insert_mem_bar(Op_MemBarCPUOrder); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4131 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4132 // paths into result_reg: |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4133 enum { |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4134 _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
|
4135 _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
|
4136 _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
|
4137 _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
|
4138 PATH_LIMIT |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4139 }; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4140 RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4141 result_val = new(C, PATH_LIMIT) PhiNode(result_reg, |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4142 TypeInstPtr::NOTNULL); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4143 PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4144 PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4145 TypePtr::BOTTOM); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4146 record_for_igvn(result_reg); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4147 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4148 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4149 int raw_adr_idx = Compile::AliasIdxRaw; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4150 const bool raw_mem_only = true; |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4151 |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4152 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4153 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
|
4154 if (array_ctl != NULL) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4155 // It's an array. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4156 PreserveJVMState pjvms(this); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4157 set_control(array_ctl); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4158 Node* obj_length = load_array_length(obj); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4159 Node* obj_size = NULL; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4160 Node* alloc_obj = new_array(obj_klass, obj_length, 0, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4161 raw_mem_only, &obj_size); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4162 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4163 if (!use_ReduceInitialCardMarks()) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4164 // 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
|
4165 // 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
|
4166 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
|
4167 if (is_obja != NULL) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4168 PreserveJVMState pjvms2(this); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4169 set_control(is_obja); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4170 // 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
|
4171 bool disjoint_bases = true; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4172 bool length_never_negative = true; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4173 generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4174 obj, intcon(0), alloc_obj, intcon(0), |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4175 obj_length, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4176 disjoint_bases, length_never_negative); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4177 result_reg->init_req(_objArray_path, control()); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4178 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
|
4179 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
|
4180 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
|
4181 } |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4182 } |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4183 // 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
|
4184 // (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
|
4185 // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
986
diff
changeset
|
4186 // 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
|
4187 // simulate a fresh allocation, so that no further |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
986
diff
changeset
|
4188 // 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
|
4189 // the object.) |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4190 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4191 if (!stopped()) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4192 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
|
4193 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4194 // Present the results of the copy. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4195 result_reg->init_req(_array_path, control()); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4196 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
|
4197 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
|
4198 result_mem ->set_req(_array_path, reset_memory()); |
0 | 4199 } |
4200 } | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4201 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4202 // 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
|
4203 // The paths which do not pass are accumulated in the slow_region. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4204 RegionNode* slow_region = new (C, 1) RegionNode(1); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4205 record_for_igvn(slow_region); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4206 if (!stopped()) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4207 // 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
|
4208 // 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
|
4209 // 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
|
4210 // 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
|
4211 // 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
|
4212 // 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
|
4213 // Object clone(). |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4214 if (is_virtual) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4215 generate_virtual_guard(obj_klass, slow_region); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4216 } |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4217 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4218 // 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
|
4219 // 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
|
4220 // 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
|
4221 generate_access_flags_guard(obj_klass, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4222 // Test both conditions: |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4223 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
|
4224 // Must be cloneable but not finalizer: |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4225 JVM_ACC_IS_CLONEABLE, |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4226 slow_region); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4227 } |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4228 |
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4229 if (!stopped()) { |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4230 // 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
|
4231 PreserveJVMState pjvms(this); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4232 Node* obj_size = NULL; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4233 Node* alloc_obj = new_instance(obj_klass, NULL, raw_mem_only, &obj_size); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4234 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4235 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
|
4236 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4237 // Present the results of the slow call. |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4238 result_reg->init_req(_instance_path, control()); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4239 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
|
4240 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
|
4241 result_mem ->set_req(_instance_path, reset_memory()); |
0 | 4242 } |
4243 | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4244 // 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
|
4245 set_control(_gvn.transform(slow_region)); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4246 if (!stopped()) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4247 PreserveJVMState pjvms(this); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4248 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
|
4249 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
|
4250 // 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
|
4251 result_reg->init_req(_slow_path, control()); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4252 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
|
4253 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
|
4254 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
|
4255 } |
902
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4256 |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4257 // Return the combined state. |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4258 set_control( _gvn.transform(result_reg) ); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4259 set_i_o( _gvn.transform(result_i_o) ); |
fc2281ddce3c
6868269: CompileTheWorld assertion failure introduced by the reexecute bit implementation
cfang
parents:
900
diff
changeset
|
4260 set_all_memory( _gvn.transform(result_mem) ); |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
896
diff
changeset
|
4261 } //original reexecute and sp are set back here |
0 | 4262 |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4263 push(_gvn.transform(result_val)); |
0 | 4264 |
4265 return true; | |
4266 } | |
4267 | |
4268 | |
4269 // constants for computing the copy function | |
4270 enum { | |
4271 COPYFUNC_UNALIGNED = 0, | |
4272 COPYFUNC_ALIGNED = 1, // src, dest aligned to HeapWordSize | |
4273 COPYFUNC_CONJOINT = 0, | |
4274 COPYFUNC_DISJOINT = 2 // src != dest, or transfer can descend | |
4275 }; | |
4276 | |
4277 // Note: The condition "disjoint" applies also for overlapping copies | |
4278 // where an descending copy is permitted (i.e., dest_offset <= src_offset). | |
4279 static address | |
4280 select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name) { | |
4281 int selector = | |
4282 (aligned ? COPYFUNC_ALIGNED : COPYFUNC_UNALIGNED) + | |
4283 (disjoint ? COPYFUNC_DISJOINT : COPYFUNC_CONJOINT); | |
4284 | |
4285 #define RETURN_STUB(xxx_arraycopy) { \ | |
4286 name = #xxx_arraycopy; \ | |
4287 return StubRoutines::xxx_arraycopy(); } | |
4288 | |
4289 switch (t) { | |
4290 case T_BYTE: | |
4291 case T_BOOLEAN: | |
4292 switch (selector) { | |
4293 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jbyte_arraycopy); | |
4294 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jbyte_arraycopy); | |
4295 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jbyte_disjoint_arraycopy); | |
4296 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jbyte_disjoint_arraycopy); | |
4297 } | |
4298 case T_CHAR: | |
4299 case T_SHORT: | |
4300 switch (selector) { | |
4301 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jshort_arraycopy); | |
4302 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jshort_arraycopy); | |
4303 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jshort_disjoint_arraycopy); | |
4304 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jshort_disjoint_arraycopy); | |
4305 } | |
4306 case T_INT: | |
4307 case T_FLOAT: | |
4308 switch (selector) { | |
4309 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jint_arraycopy); | |
4310 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jint_arraycopy); | |
4311 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jint_disjoint_arraycopy); | |
4312 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jint_disjoint_arraycopy); | |
4313 } | |
4314 case T_DOUBLE: | |
4315 case T_LONG: | |
4316 switch (selector) { | |
4317 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jlong_arraycopy); | |
4318 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jlong_arraycopy); | |
4319 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(jlong_disjoint_arraycopy); | |
4320 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_jlong_disjoint_arraycopy); | |
4321 } | |
4322 case T_ARRAY: | |
4323 case T_OBJECT: | |
4324 switch (selector) { | |
4325 case COPYFUNC_CONJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(oop_arraycopy); | |
4326 case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_oop_arraycopy); | |
4327 case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB(oop_disjoint_arraycopy); | |
4328 case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB(arrayof_oop_disjoint_arraycopy); | |
4329 } | |
4330 default: | |
4331 ShouldNotReachHere(); | |
4332 return NULL; | |
4333 } | |
4334 | |
4335 #undef RETURN_STUB | |
4336 } | |
4337 | |
4338 //------------------------------basictype2arraycopy---------------------------- | |
4339 address LibraryCallKit::basictype2arraycopy(BasicType t, | |
4340 Node* src_offset, | |
4341 Node* dest_offset, | |
4342 bool disjoint_bases, | |
4343 const char* &name) { | |
4344 const TypeInt* src_offset_inttype = gvn().find_int_type(src_offset);; | |
4345 const TypeInt* dest_offset_inttype = gvn().find_int_type(dest_offset);; | |
4346 | |
4347 bool aligned = false; | |
4348 bool disjoint = disjoint_bases; | |
4349 | |
4350 // if the offsets are the same, we can treat the memory regions as | |
4351 // disjoint, because either the memory regions are in different arrays, | |
4352 // or they are identical (which we can treat as disjoint.) We can also | |
4353 // treat a copy with a destination index less that the source index | |
4354 // as disjoint since a low->high copy will work correctly in this case. | |
4355 if (src_offset_inttype != NULL && src_offset_inttype->is_con() && | |
4356 dest_offset_inttype != NULL && dest_offset_inttype->is_con()) { | |
4357 // both indices are constants | |
4358 int s_offs = src_offset_inttype->get_con(); | |
4359 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
|
4360 int element_size = type2aelembytes(t); |
0 | 4361 aligned = ((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) && |
4362 ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0); | |
4363 if (s_offs >= d_offs) disjoint = true; | |
4364 } else if (src_offset == dest_offset && src_offset != NULL) { | |
4365 // This can occur if the offsets are identical non-constants. | |
4366 disjoint = true; | |
4367 } | |
4368 | |
4369 return select_arraycopy_function(t, aligned, disjoint, name); | |
4370 } | |
4371 | |
4372 | |
4373 //------------------------------inline_arraycopy----------------------- | |
4374 bool LibraryCallKit::inline_arraycopy() { | |
4375 // Restore the stack and pop off the arguments. | |
4376 int nargs = 5; // 2 oops, 3 ints, no size_t or long | |
4377 assert(callee()->signature()->size() == nargs, "copy has 5 arguments"); | |
4378 | |
4379 Node *src = argument(0); | |
4380 Node *src_offset = argument(1); | |
4381 Node *dest = argument(2); | |
4382 Node *dest_offset = argument(3); | |
4383 Node *length = argument(4); | |
4384 | |
4385 // Compile time checks. If any of these checks cannot be verified at compile time, | |
4386 // we do not make a fast path for this call. Instead, we let the call remain as it | |
4387 // is. The checks we choose to mandate at compile time are: | |
4388 // | |
4389 // (1) src and dest are arrays. | |
4390 const Type* src_type = src->Value(&_gvn); | |
4391 const Type* dest_type = dest->Value(&_gvn); | |
4392 const TypeAryPtr* top_src = src_type->isa_aryptr(); | |
4393 const TypeAryPtr* top_dest = dest_type->isa_aryptr(); | |
4394 if (top_src == NULL || top_src->klass() == NULL || | |
4395 top_dest == NULL || top_dest->klass() == NULL) { | |
4396 // Conservatively insert a memory barrier on all memory slices. | |
4397 // Do not let writes into the source float below the arraycopy. | |
4398 insert_mem_bar(Op_MemBarCPUOrder); | |
4399 | |
4400 // Call StubRoutines::generic_arraycopy stub. | |
4401 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
|
4402 src, src_offset, dest, dest_offset, length); |
0 | 4403 |
4404 // Do not let reads from the destination float above the arraycopy. | |
4405 // Since we cannot type the arrays, we don't know which slices | |
4406 // might be affected. We could restrict this barrier only to those | |
4407 // memory slices which pertain to array elements--but don't bother. | |
4408 if (!InsertMemBarAfterArraycopy) | |
4409 // (If InsertMemBarAfterArraycopy, there is already one in place.) | |
4410 insert_mem_bar(Op_MemBarCPUOrder); | |
4411 return true; | |
4412 } | |
4413 | |
4414 // (2) src and dest arrays must have elements of the same BasicType | |
4415 // Figure out the size and type of the elements we will be copying. | |
4416 BasicType src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); | |
4417 BasicType dest_elem = top_dest->klass()->as_array_klass()->element_type()->basic_type(); | |
4418 if (src_elem == T_ARRAY) src_elem = T_OBJECT; | |
4419 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT; | |
4420 | |
4421 if (src_elem != dest_elem || dest_elem == T_VOID) { | |
4422 // The component types are not the same or are not recognized. Punt. | |
4423 // (But, avoid the native method wrapper to JVM_ArrayCopy.) | |
4424 generate_slow_arraycopy(TypePtr::BOTTOM, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4425 src, src_offset, dest, dest_offset, length); |
0 | 4426 return true; |
4427 } | |
4428 | |
4429 //--------------------------------------------------------------------------- | |
4430 // We will make a fast path for this call to arraycopy. | |
4431 | |
4432 // We have the following tests left to perform: | |
4433 // | |
4434 // (3) src and dest must not be null. | |
4435 // (4) src_offset must not be negative. | |
4436 // (5) dest_offset must not be negative. | |
4437 // (6) length must not be negative. | |
4438 // (7) src_offset + length must not exceed length of src. | |
4439 // (8) dest_offset + length must not exceed length of dest. | |
4440 // (9) each element of an oop array must be assignable | |
4441 | |
4442 RegionNode* slow_region = new (C, 1) RegionNode(1); | |
4443 record_for_igvn(slow_region); | |
4444 | |
4445 // (3) operands must not be null | |
4446 // We currently perform our null checks with the do_null_check routine. | |
4447 // This means that the null exceptions will be reported in the caller | |
4448 // rather than (correctly) reported inside of the native arraycopy call. | |
4449 // This should be corrected, given time. We do our null check with the | |
4450 // stack pointer restored. | |
4451 _sp += nargs; | |
4452 src = do_null_check(src, T_ARRAY); | |
4453 dest = do_null_check(dest, T_ARRAY); | |
4454 _sp -= nargs; | |
4455 | |
4456 // (4) src_offset must not be negative. | |
4457 generate_negative_guard(src_offset, slow_region); | |
4458 | |
4459 // (5) dest_offset must not be negative. | |
4460 generate_negative_guard(dest_offset, slow_region); | |
4461 | |
4462 // (6) length must not be negative (moved to generate_arraycopy()). | |
4463 // generate_negative_guard(length, slow_region); | |
4464 | |
4465 // (7) src_offset + length must not exceed length of src. | |
4466 generate_limit_guard(src_offset, length, | |
4467 load_array_length(src), | |
4468 slow_region); | |
4469 | |
4470 // (8) dest_offset + length must not exceed length of dest. | |
4471 generate_limit_guard(dest_offset, length, | |
4472 load_array_length(dest), | |
4473 slow_region); | |
4474 | |
4475 // (9) each element of an oop array must be assignable | |
4476 // The generate_arraycopy subroutine checks this. | |
4477 | |
4478 // This is where the memory effects are placed: | |
4479 const TypePtr* adr_type = TypeAryPtr::get_array_body_type(dest_elem); | |
4480 generate_arraycopy(adr_type, dest_elem, | |
4481 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
|
4482 false, false, slow_region); |
0 | 4483 |
4484 return true; | |
4485 } | |
4486 | |
4487 //-----------------------------generate_arraycopy---------------------- | |
4488 // Generate an optimized call to arraycopy. | |
4489 // Caller must guard against non-arrays. | |
4490 // Caller must determine a common array basic-type for both arrays. | |
4491 // Caller must validate offsets against array bounds. | |
4492 // The slow_region has already collected guard failure paths | |
4493 // (such as out of bounds length or non-conformable array types). | |
4494 // The generated code has this shape, in general: | |
4495 // | |
4496 // if (length == 0) return // via zero_path | |
4497 // slowval = -1 | |
4498 // if (types unknown) { | |
4499 // slowval = call generic copy loop | |
4500 // if (slowval == 0) return // via checked_path | |
4501 // } else if (indexes in bounds) { | |
4502 // if ((is object array) && !(array type check)) { | |
4503 // slowval = call checked copy loop | |
4504 // if (slowval == 0) return // via checked_path | |
4505 // } else { | |
4506 // call bulk copy loop | |
4507 // return // via fast_path | |
4508 // } | |
4509 // } | |
4510 // // adjust params for remaining work: | |
4511 // if (slowval != -1) { | |
4512 // n = -1^slowval; src_offset += n; dest_offset += n; length -= n | |
4513 // } | |
4514 // slow_region: | |
4515 // call slow arraycopy(src, src_offset, dest, dest_offset, length) | |
4516 // return // via slow_call_path | |
4517 // | |
4518 // This routine is used from several intrinsics: System.arraycopy, | |
4519 // Object.clone (the array subcase), and Arrays.copyOf[Range]. | |
4520 // | |
4521 void | |
4522 LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, | |
4523 BasicType basic_elem_type, | |
4524 Node* src, Node* src_offset, | |
4525 Node* dest, Node* dest_offset, | |
4526 Node* copy_length, | |
4527 bool disjoint_bases, | |
4528 bool length_never_negative, | |
4529 RegionNode* slow_region) { | |
4530 | |
4531 if (slow_region == NULL) { | |
4532 slow_region = new(C,1) RegionNode(1); | |
4533 record_for_igvn(slow_region); | |
4534 } | |
4535 | |
4536 Node* original_dest = dest; | |
4537 AllocateArrayNode* alloc = NULL; // used for zeroing, if needed | |
4538 bool must_clear_dest = false; | |
4539 | |
4540 // See if this is the initialization of a newly-allocated array. | |
4541 // If so, we will take responsibility here for initializing it to zero. | |
4542 // (Note: Because tightly_coupled_allocation performs checks on the | |
4543 // out-edges of the dest, we need to avoid making derived pointers | |
4544 // from it until we have checked its uses.) | |
4545 if (ReduceBulkZeroing | |
4546 && !ZeroTLAB // pointless if already zeroed | |
4547 && basic_elem_type != T_CONFLICT // avoid corner case | |
4548 && !_gvn.eqv_uncast(src, dest) | |
4549 && ((alloc = tightly_coupled_allocation(dest, slow_region)) | |
4550 != NULL) | |
34
545c277a3ecf
6667581: Don't generate initialization (by 0) code for arrays with size 0
kvn
parents:
29
diff
changeset
|
4551 && _gvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0 |
0 | 4552 && alloc->maybe_set_complete(&_gvn)) { |
4553 // "You break it, you buy it." | |
4554 InitializeNode* init = alloc->initialization(); | |
4555 assert(init->is_complete(), "we just did this"); | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4556 assert(dest->is_CheckCastPP(), "sanity"); |
0 | 4557 assert(dest->in(0)->in(0) == init, "dest pinned"); |
4558 adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory | |
4559 // From this point on, every exit path is responsible for | |
4560 // initializing any non-copied parts of the object to zero. | |
4561 must_clear_dest = true; | |
4562 } else { | |
4563 // No zeroing elimination here. | |
4564 alloc = NULL; | |
4565 //original_dest = dest; | |
4566 //must_clear_dest = false; | |
4567 } | |
4568 | |
4569 // Results are placed here: | |
4570 enum { fast_path = 1, // normal void-returning assembly stub | |
4571 checked_path = 2, // special assembly stub with cleanup | |
4572 slow_call_path = 3, // something went wrong; call the VM | |
4573 zero_path = 4, // bypass when length of copy is zero | |
4574 bcopy_path = 5, // copy primitive array by 64-bit blocks | |
4575 PATH_LIMIT = 6 | |
4576 }; | |
4577 RegionNode* result_region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
4578 PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_region, Type::ABIO); | |
4579 PhiNode* result_memory = new(C, PATH_LIMIT) PhiNode(result_region, Type::MEMORY, adr_type); | |
4580 record_for_igvn(result_region); | |
4581 _gvn.set_type_bottom(result_i_o); | |
4582 _gvn.set_type_bottom(result_memory); | |
4583 assert(adr_type != TypePtr::BOTTOM, "must be RawMem or a T[] slice"); | |
4584 | |
4585 // The slow_control path: | |
4586 Node* slow_control; | |
4587 Node* slow_i_o = i_o(); | |
4588 Node* slow_mem = memory(adr_type); | |
4589 debug_only(slow_control = (Node*) badAddress); | |
4590 | |
4591 // Checked control path: | |
4592 Node* checked_control = top(); | |
4593 Node* checked_mem = NULL; | |
4594 Node* checked_i_o = NULL; | |
4595 Node* checked_value = NULL; | |
4596 | |
4597 if (basic_elem_type == T_CONFLICT) { | |
4598 assert(!must_clear_dest, ""); | |
4599 Node* cv = generate_generic_arraycopy(adr_type, | |
4600 src, src_offset, dest, dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4601 copy_length); |
0 | 4602 if (cv == NULL) cv = intcon(-1); // failure (no stub available) |
4603 checked_control = control(); | |
4604 checked_i_o = i_o(); | |
4605 checked_mem = memory(adr_type); | |
4606 checked_value = cv; | |
4607 set_control(top()); // no fast path | |
4608 } | |
4609 | |
4610 Node* not_pos = generate_nonpositive_guard(copy_length, length_never_negative); | |
4611 if (not_pos != NULL) { | |
4612 PreserveJVMState pjvms(this); | |
4613 set_control(not_pos); | |
4614 | |
4615 // (6) length must not be negative. | |
4616 if (!length_never_negative) { | |
4617 generate_negative_guard(copy_length, slow_region); | |
4618 } | |
4619 | |
836
4325cdaa78ad
6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents:
833
diff
changeset
|
4620 // copy_length is 0. |
0 | 4621 if (!stopped() && must_clear_dest) { |
4622 Node* dest_length = alloc->in(AllocateNode::ALength); | |
4623 if (_gvn.eqv_uncast(copy_length, dest_length) | |
4624 || _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
|
4625 // There is no zeroing to do. No need for a secondary raw memory barrier. |
0 | 4626 } else { |
4627 // Clear the whole thing since there are no source elements to copy. | |
4628 generate_clear_array(adr_type, dest, basic_elem_type, | |
4629 intcon(0), NULL, | |
4630 alloc->in(AllocateNode::AllocSize)); | |
836
4325cdaa78ad
6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents:
833
diff
changeset
|
4631 // 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
|
4632 // 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
|
4633 // 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
|
4634 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
|
4635 Compile::AliasIdxRaw, |
4325cdaa78ad
6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents:
833
diff
changeset
|
4636 top())->as_Initialize(); |
4325cdaa78ad
6857661: 64-bit server VM: assert(is_Initialize(),"invalid node class")
kvn
parents:
833
diff
changeset
|
4637 init->set_complete(&_gvn); // (there is no corresponding AllocateNode) |
0 | 4638 } |
4639 } | |
4640 | |
4641 // Present the results of the fast call. | |
4642 result_region->init_req(zero_path, control()); | |
4643 result_i_o ->init_req(zero_path, i_o()); | |
4644 result_memory->init_req(zero_path, memory(adr_type)); | |
4645 } | |
4646 | |
4647 if (!stopped() && must_clear_dest) { | |
4648 // We have to initialize the *uncopied* part of the array to zero. | |
4649 // The copy destination is the slice dest[off..off+len]. The other slices | |
4650 // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length]. | |
4651 Node* dest_size = alloc->in(AllocateNode::AllocSize); | |
4652 Node* dest_length = alloc->in(AllocateNode::ALength); | |
4653 Node* dest_tail = _gvn.transform( new(C,3) AddINode(dest_offset, | |
4654 copy_length) ); | |
4655 | |
4656 // If there is a head section that needs zeroing, do it now. | |
4657 if (find_int_con(dest_offset, -1) != 0) { | |
4658 generate_clear_array(adr_type, dest, basic_elem_type, | |
4659 intcon(0), dest_offset, | |
4660 NULL); | |
4661 } | |
4662 | |
4663 // Next, perform a dynamic check on the tail length. | |
4664 // It is often zero, and we can win big if we prove this. | |
4665 // There are two wins: Avoid generating the ClearArray | |
4666 // with its attendant messy index arithmetic, and upgrade | |
4667 // the copy to a more hardware-friendly word size of 64 bits. | |
4668 Node* tail_ctl = NULL; | |
4669 if (!stopped() && !_gvn.eqv_uncast(dest_tail, dest_length)) { | |
4670 Node* cmp_lt = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) ); | |
4671 Node* bol_lt = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) ); | |
4672 tail_ctl = generate_slow_guard(bol_lt, NULL); | |
4673 assert(tail_ctl != NULL || !stopped(), "must be an outcome"); | |
4674 } | |
4675 | |
4676 // At this point, let's assume there is no tail. | |
4677 if (!stopped() && alloc != NULL && basic_elem_type != T_OBJECT) { | |
4678 // There is no tail. Try an upgrade to a 64-bit copy. | |
4679 bool didit = false; | |
4680 { PreserveJVMState pjvms(this); | |
4681 didit = generate_block_arraycopy(adr_type, basic_elem_type, alloc, | |
4682 src, src_offset, dest, dest_offset, | |
4683 dest_size); | |
4684 if (didit) { | |
4685 // Present the results of the block-copying fast call. | |
4686 result_region->init_req(bcopy_path, control()); | |
4687 result_i_o ->init_req(bcopy_path, i_o()); | |
4688 result_memory->init_req(bcopy_path, memory(adr_type)); | |
4689 } | |
4690 } | |
4691 if (didit) | |
4692 set_control(top()); // no regular fast path | |
4693 } | |
4694 | |
4695 // Clear the tail, if any. | |
4696 if (tail_ctl != NULL) { | |
4697 Node* notail_ctl = stopped() ? NULL : control(); | |
4698 set_control(tail_ctl); | |
4699 if (notail_ctl == NULL) { | |
4700 generate_clear_array(adr_type, dest, basic_elem_type, | |
4701 dest_tail, NULL, | |
4702 dest_size); | |
4703 } else { | |
4704 // Make a local merge. | |
4705 Node* done_ctl = new(C,3) RegionNode(3); | |
4706 Node* done_mem = new(C,3) PhiNode(done_ctl, Type::MEMORY, adr_type); | |
4707 done_ctl->init_req(1, notail_ctl); | |
4708 done_mem->init_req(1, memory(adr_type)); | |
4709 generate_clear_array(adr_type, dest, basic_elem_type, | |
4710 dest_tail, NULL, | |
4711 dest_size); | |
4712 done_ctl->init_req(2, control()); | |
4713 done_mem->init_req(2, memory(adr_type)); | |
4714 set_control( _gvn.transform(done_ctl) ); | |
4715 set_memory( _gvn.transform(done_mem), adr_type ); | |
4716 } | |
4717 } | |
4718 } | |
4719 | |
4720 BasicType copy_type = basic_elem_type; | |
4721 assert(basic_elem_type != T_ARRAY, "caller must fix this"); | |
4722 if (!stopped() && copy_type == T_OBJECT) { | |
4723 // If src and dest have compatible element types, we can copy bits. | |
4724 // Types S[] and D[] are compatible if D is a supertype of S. | |
4725 // | |
4726 // If they are not, we will use checked_oop_disjoint_arraycopy, | |
4727 // which performs a fast optimistic per-oop check, and backs off | |
4728 // further to JVM_ArrayCopy on the first per-oop check that fails. | |
4729 // (Actually, we don't move raw bits only; the GC requires card marks.) | |
4730 | |
4731 // Get the klassOop for both src and dest | |
4732 Node* src_klass = load_object_klass(src); | |
4733 Node* dest_klass = load_object_klass(dest); | |
4734 | |
4735 // Generate the subtype check. | |
4736 // This might fold up statically, or then again it might not. | |
4737 // | |
4738 // Non-static example: Copying List<String>.elements to a new String[]. | |
4739 // The backing store for a List<String> is always an Object[], | |
4740 // but its elements are always type String, if the generic types | |
4741 // are correct at the source level. | |
4742 // | |
4743 // Test S[] against D[], not S against D, because (probably) | |
4744 // the secondary supertype cache is less busy for S[] than S. | |
4745 // This usually only matters when D is an interface. | |
4746 Node* not_subtype_ctrl = gen_subtype_check(src_klass, dest_klass); | |
4747 // Plug failing path into checked_oop_disjoint_arraycopy | |
4748 if (not_subtype_ctrl != top()) { | |
4749 PreserveJVMState pjvms(this); | |
4750 set_control(not_subtype_ctrl); | |
4751 // (At this point we can assume disjoint_bases, since types differ.) | |
4752 int ek_offset = objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc); | |
4753 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
|
4754 Node* n1 = LoadKlassNode::make(_gvn, immutable_memory(), p1, TypeRawPtr::BOTTOM); |
0 | 4755 Node* dest_elem_klass = _gvn.transform(n1); |
4756 Node* cv = generate_checkcast_arraycopy(adr_type, | |
4757 dest_elem_klass, | |
4758 src, src_offset, dest, dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4759 copy_length); |
0 | 4760 if (cv == NULL) cv = intcon(-1); // failure (no stub available) |
4761 checked_control = control(); | |
4762 checked_i_o = i_o(); | |
4763 checked_mem = memory(adr_type); | |
4764 checked_value = cv; | |
4765 } | |
4766 // At this point we know we do not need type checks on oop stores. | |
4767 | |
4768 // Let's see if we need card marks: | |
4769 if (alloc != NULL && use_ReduceInitialCardMarks()) { | |
4770 // 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
|
4771 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
|
4772 assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type), |
0 | 4773 "sizes agree"); |
4774 } | |
4775 } | |
4776 | |
4777 if (!stopped()) { | |
4778 // Generate the fast path, if possible. | |
4779 PreserveJVMState pjvms(this); | |
4780 generate_unchecked_arraycopy(adr_type, copy_type, disjoint_bases, | |
4781 src, src_offset, dest, dest_offset, | |
4782 ConvI2X(copy_length)); | |
4783 | |
4784 // Present the results of the fast call. | |
4785 result_region->init_req(fast_path, control()); | |
4786 result_i_o ->init_req(fast_path, i_o()); | |
4787 result_memory->init_req(fast_path, memory(adr_type)); | |
4788 } | |
4789 | |
4790 // Here are all the slow paths up to this point, in one bundle: | |
4791 slow_control = top(); | |
4792 if (slow_region != NULL) | |
4793 slow_control = _gvn.transform(slow_region); | |
4794 debug_only(slow_region = (RegionNode*)badAddress); | |
4795 | |
4796 set_control(checked_control); | |
4797 if (!stopped()) { | |
4798 // Clean up after the checked call. | |
4799 // The returned value is either 0 or -1^K, | |
4800 // where K = number of partially transferred array elements. | |
4801 Node* cmp = _gvn.transform( new(C, 3) CmpINode(checked_value, intcon(0)) ); | |
4802 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); | |
4803 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); | |
4804 | |
4805 // If it is 0, we are done, so transfer to the end. | |
4806 Node* checks_done = _gvn.transform( new(C, 1) IfTrueNode(iff) ); | |
4807 result_region->init_req(checked_path, checks_done); | |
4808 result_i_o ->init_req(checked_path, checked_i_o); | |
4809 result_memory->init_req(checked_path, checked_mem); | |
4810 | |
4811 // If it is not zero, merge into the slow call. | |
4812 set_control( _gvn.transform( new(C, 1) IfFalseNode(iff) )); | |
4813 RegionNode* slow_reg2 = new(C, 3) RegionNode(3); | |
4814 PhiNode* slow_i_o2 = new(C, 3) PhiNode(slow_reg2, Type::ABIO); | |
4815 PhiNode* slow_mem2 = new(C, 3) PhiNode(slow_reg2, Type::MEMORY, adr_type); | |
4816 record_for_igvn(slow_reg2); | |
4817 slow_reg2 ->init_req(1, slow_control); | |
4818 slow_i_o2 ->init_req(1, slow_i_o); | |
4819 slow_mem2 ->init_req(1, slow_mem); | |
4820 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
|
4821 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
|
4822 slow_mem2 ->init_req(2, checked_mem); |
0 | 4823 |
4824 slow_control = _gvn.transform(slow_reg2); | |
4825 slow_i_o = _gvn.transform(slow_i_o2); | |
4826 slow_mem = _gvn.transform(slow_mem2); | |
4827 | |
4828 if (alloc != NULL) { | |
4829 // We'll restart from the very beginning, after zeroing the whole thing. | |
4830 // This can cause double writes, but that's OK since dest is brand new. | |
4831 // So we ignore the low 31 bits of the value returned from the stub. | |
4832 } else { | |
4833 // We must continue the copy exactly where it failed, or else | |
4834 // another thread might see the wrong number of writes to dest. | |
4835 Node* checked_offset = _gvn.transform( new(C, 3) XorINode(checked_value, intcon(-1)) ); | |
4836 Node* slow_offset = new(C, 3) PhiNode(slow_reg2, TypeInt::INT); | |
4837 slow_offset->init_req(1, intcon(0)); | |
4838 slow_offset->init_req(2, checked_offset); | |
4839 slow_offset = _gvn.transform(slow_offset); | |
4840 | |
4841 // Adjust the arguments by the conditionally incoming offset. | |
4842 Node* src_off_plus = _gvn.transform( new(C, 3) AddINode(src_offset, slow_offset) ); | |
4843 Node* dest_off_plus = _gvn.transform( new(C, 3) AddINode(dest_offset, slow_offset) ); | |
4844 Node* length_minus = _gvn.transform( new(C, 3) SubINode(copy_length, slow_offset) ); | |
4845 | |
4846 // Tweak the node variables to adjust the code produced below: | |
4847 src_offset = src_off_plus; | |
4848 dest_offset = dest_off_plus; | |
4849 copy_length = length_minus; | |
4850 } | |
4851 } | |
4852 | |
4853 set_control(slow_control); | |
4854 if (!stopped()) { | |
4855 // Generate the slow path, if needed. | |
4856 PreserveJVMState pjvms(this); // replace_in_map may trash the map | |
4857 | |
4858 set_memory(slow_mem, adr_type); | |
4859 set_i_o(slow_i_o); | |
4860 | |
4861 if (must_clear_dest) { | |
4862 generate_clear_array(adr_type, dest, basic_elem_type, | |
4863 intcon(0), NULL, | |
4864 alloc->in(AllocateNode::AllocSize)); | |
4865 } | |
4866 | |
4867 generate_slow_arraycopy(adr_type, | |
4868 src, src_offset, dest, dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
4869 copy_length); |
0 | 4870 |
4871 result_region->init_req(slow_call_path, control()); | |
4872 result_i_o ->init_req(slow_call_path, i_o()); | |
4873 result_memory->init_req(slow_call_path, memory(adr_type)); | |
4874 } | |
4875 | |
4876 // Remove unused edges. | |
4877 for (uint i = 1; i < result_region->req(); i++) { | |
4878 if (result_region->in(i) == NULL) | |
4879 result_region->init_req(i, top()); | |
4880 } | |
4881 | |
4882 // Finished; return the combined state. | |
4883 set_control( _gvn.transform(result_region) ); | |
4884 set_i_o( _gvn.transform(result_i_o) ); | |
4885 set_memory( _gvn.transform(result_memory), adr_type ); | |
4886 | |
4887 // The memory edges above are precise in order to model effects around | |
605 | 4888 // array copies accurately to allow value numbering of field loads around |
0 | 4889 // arraycopy. Such field loads, both before and after, are common in Java |
4890 // collections and similar classes involving header/array data structures. | |
4891 // | |
4892 // But with low number of register or when some registers are used or killed | |
4893 // by arraycopy calls it causes registers spilling on stack. See 6544710. | |
4894 // The next memory barrier is added to avoid it. If the arraycopy can be | |
4895 // optimized away (which it can, sometimes) then we can manually remove | |
4896 // the membar also. | |
958
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4897 // |
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4898 // Do not let reads from the cloned object float above the arraycopy. |
c7e94e8fff43
6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)
kvn
parents:
950
diff
changeset
|
4899 if (InsertMemBarAfterArraycopy || alloc != NULL) |
0 | 4900 insert_mem_bar(Op_MemBarCPUOrder); |
4901 } | |
4902 | |
4903 | |
4904 // Helper function which determines if an arraycopy immediately follows | |
4905 // an allocation, with no intervening tests or other escapes for the object. | |
4906 AllocateArrayNode* | |
4907 LibraryCallKit::tightly_coupled_allocation(Node* ptr, | |
4908 RegionNode* slow_region) { | |
4909 if (stopped()) return NULL; // no fast path | |
4910 if (C->AliasLevel() == 0) return NULL; // no MergeMems around | |
4911 | |
4912 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(ptr, &_gvn); | |
4913 if (alloc == NULL) return NULL; | |
4914 | |
4915 Node* rawmem = memory(Compile::AliasIdxRaw); | |
4916 // Is the allocation's memory state untouched? | |
4917 if (!(rawmem->is_Proj() && rawmem->in(0)->is_Initialize())) { | |
4918 // Bail out if there have been raw-memory effects since the allocation. | |
4919 // (Example: There might have been a call or safepoint.) | |
4920 return NULL; | |
4921 } | |
4922 rawmem = rawmem->in(0)->as_Initialize()->memory(Compile::AliasIdxRaw); | |
4923 if (!(rawmem->is_Proj() && rawmem->in(0) == alloc)) { | |
4924 return NULL; | |
4925 } | |
4926 | |
4927 // There must be no unexpected observers of this allocation. | |
4928 for (DUIterator_Fast imax, i = ptr->fast_outs(imax); i < imax; i++) { | |
4929 Node* obs = ptr->fast_out(i); | |
4930 if (obs != this->map()) { | |
4931 return NULL; | |
4932 } | |
4933 } | |
4934 | |
4935 // This arraycopy must unconditionally follow the allocation of the ptr. | |
4936 Node* alloc_ctl = ptr->in(0); | |
4937 assert(just_allocated_object(alloc_ctl) == ptr, "most recent allo"); | |
4938 | |
4939 Node* ctl = control(); | |
4940 while (ctl != alloc_ctl) { | |
4941 // There may be guards which feed into the slow_region. | |
4942 // Any other control flow means that we might not get a chance | |
4943 // to finish initializing the allocated object. | |
4944 if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) { | |
4945 IfNode* iff = ctl->in(0)->as_If(); | |
4946 Node* not_ctl = iff->proj_out(1 - ctl->as_Proj()->_con); | |
4947 assert(not_ctl != NULL && not_ctl != ctl, "found alternate"); | |
4948 if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) { | |
4949 ctl = iff->in(0); // This test feeds the known slow_region. | |
4950 continue; | |
4951 } | |
4952 // One more try: Various low-level checks bottom out in | |
4953 // uncommon traps. If the debug-info of the trap omits | |
4954 // any reference to the allocation, as we've already | |
4955 // observed, then there can be no objection to the trap. | |
4956 bool found_trap = false; | |
4957 for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) { | |
4958 Node* obs = not_ctl->fast_out(j); | |
4959 if (obs->in(0) == not_ctl && obs->is_Call() && | |
4960 (obs->as_Call()->entry_point() == | |
4961 SharedRuntime::uncommon_trap_blob()->instructions_begin())) { | |
4962 found_trap = true; break; | |
4963 } | |
4964 } | |
4965 if (found_trap) { | |
4966 ctl = iff->in(0); // This test feeds a harmless uncommon trap. | |
4967 continue; | |
4968 } | |
4969 } | |
4970 return NULL; | |
4971 } | |
4972 | |
4973 // If we get this far, we have an allocation which immediately | |
4974 // precedes the arraycopy, and we can take over zeroing the new object. | |
4975 // The arraycopy will finish the initialization, and provide | |
4976 // a new control state to which we will anchor the destination pointer. | |
4977 | |
4978 return alloc; | |
4979 } | |
4980 | |
4981 // Helper for initialization of arrays, creating a ClearArray. | |
4982 // It writes zero bits in [start..end), within the body of an array object. | |
4983 // The memory effects are all chained onto the 'adr_type' alias category. | |
4984 // | |
4985 // Since the object is otherwise uninitialized, we are free | |
4986 // to put a little "slop" around the edges of the cleared area, | |
4987 // as long as it does not go back into the array's header, | |
4988 // or beyond the array end within the heap. | |
4989 // | |
4990 // The lower edge can be rounded down to the nearest jint and the | |
4991 // upper edge can be rounded up to the nearest MinObjAlignmentInBytes. | |
4992 // | |
4993 // Arguments: | |
4994 // adr_type memory slice where writes are generated | |
4995 // dest oop of the destination array | |
4996 // basic_elem_type element type of the destination | |
4997 // slice_idx array index of first element to store | |
4998 // slice_len number of elements to store (or NULL) | |
4999 // dest_size total size in bytes of the array object | |
5000 // | |
5001 // Exactly one of slice_len or dest_size must be non-NULL. | |
5002 // If dest_size is non-NULL, zeroing extends to the end of the object. | |
5003 // If slice_len is non-NULL, the slice_idx value must be a constant. | |
5004 void | |
5005 LibraryCallKit::generate_clear_array(const TypePtr* adr_type, | |
5006 Node* dest, | |
5007 BasicType basic_elem_type, | |
5008 Node* slice_idx, | |
5009 Node* slice_len, | |
5010 Node* dest_size) { | |
5011 // one or the other but not both of slice_len and dest_size: | |
5012 assert((slice_len != NULL? 1: 0) + (dest_size != NULL? 1: 0) == 1, ""); | |
5013 if (slice_len == NULL) slice_len = top(); | |
5014 if (dest_size == NULL) dest_size = top(); | |
5015 | |
5016 // operate on this memory slice: | |
5017 Node* mem = memory(adr_type); // memory slice to operate on | |
5018 | |
5019 // scaling and rounding of indexes: | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
5020 int scale = exact_log2(type2aelembytes(basic_elem_type)); |
0 | 5021 int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); |
5022 int clear_low = (-1 << scale) & (BytesPerInt - 1); | |
5023 int bump_bit = (-1 << scale) & BytesPerInt; | |
5024 | |
5025 // determine constant starts and ends | |
5026 const intptr_t BIG_NEG = -128; | |
5027 assert(BIG_NEG + 2*abase < 0, "neg enough"); | |
5028 intptr_t slice_idx_con = (intptr_t) find_int_con(slice_idx, BIG_NEG); | |
5029 intptr_t slice_len_con = (intptr_t) find_int_con(slice_len, BIG_NEG); | |
5030 if (slice_len_con == 0) { | |
5031 return; // nothing to do here | |
5032 } | |
5033 intptr_t start_con = (abase + (slice_idx_con << scale)) & ~clear_low; | |
5034 intptr_t end_con = find_intptr_t_con(dest_size, -1); | |
5035 if (slice_idx_con >= 0 && slice_len_con >= 0) { | |
5036 assert(end_con < 0, "not two cons"); | |
5037 end_con = round_to(abase + ((slice_idx_con + slice_len_con) << scale), | |
5038 BytesPerLong); | |
5039 } | |
5040 | |
5041 if (start_con >= 0 && end_con >= 0) { | |
5042 // Constant start and end. Simple. | |
5043 mem = ClearArrayNode::clear_memory(control(), mem, dest, | |
5044 start_con, end_con, &_gvn); | |
5045 } else if (start_con >= 0 && dest_size != top()) { | |
5046 // Constant start, pre-rounded end after the tail of the array. | |
5047 Node* end = dest_size; | |
5048 mem = ClearArrayNode::clear_memory(control(), mem, dest, | |
5049 start_con, end, &_gvn); | |
5050 } else if (start_con >= 0 && slice_len != top()) { | |
5051 // Constant start, non-constant end. End needs rounding up. | |
5052 // End offset = round_up(abase + ((slice_idx_con + slice_len) << scale), 8) | |
5053 intptr_t end_base = abase + (slice_idx_con << scale); | |
5054 int end_round = (-1 << scale) & (BytesPerLong - 1); | |
5055 Node* end = ConvI2X(slice_len); | |
5056 if (scale != 0) | |
5057 end = _gvn.transform( new(C,3) LShiftXNode(end, intcon(scale) )); | |
5058 end_base += end_round; | |
5059 end = _gvn.transform( new(C,3) AddXNode(end, MakeConX(end_base)) ); | |
5060 end = _gvn.transform( new(C,3) AndXNode(end, MakeConX(~end_round)) ); | |
5061 mem = ClearArrayNode::clear_memory(control(), mem, dest, | |
5062 start_con, end, &_gvn); | |
5063 } else if (start_con < 0 && dest_size != top()) { | |
5064 // Non-constant start, pre-rounded end after the tail of the array. | |
5065 // This is almost certainly a "round-to-end" operation. | |
5066 Node* start = slice_idx; | |
5067 start = ConvI2X(start); | |
5068 if (scale != 0) | |
5069 start = _gvn.transform( new(C,3) LShiftXNode( start, intcon(scale) )); | |
5070 start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(abase)) ); | |
5071 if ((bump_bit | clear_low) != 0) { | |
5072 int to_clear = (bump_bit | clear_low); | |
5073 // Align up mod 8, then store a jint zero unconditionally | |
5074 // 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
|
5075 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
|
5076 < 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
|
5077 bump_bit = 0; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5078 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
|
5079 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5080 // Bump 'start' up to (or past) the next jint boundary: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5081 start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5082 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
|
5083 } |
0 | 5084 // Round bumped 'start' down to jlong boundary in body of array. |
5085 start = _gvn.transform( new(C,3) 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
|
5086 if (bump_bit != 0) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5087 // Store a zero to the immediately preceding jint: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5088 Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-bump_bit)) ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5089 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
|
5090 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
|
5091 mem = _gvn.transform(mem); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
34
diff
changeset
|
5092 } |
0 | 5093 } |
5094 Node* end = dest_size; // pre-rounded | |
5095 mem = ClearArrayNode::clear_memory(control(), mem, dest, | |
5096 start, end, &_gvn); | |
5097 } else { | |
5098 // Non-constant start, unrounded non-constant end. | |
5099 // (Nobody zeroes a random midsection of an array using this routine.) | |
5100 ShouldNotReachHere(); // fix caller | |
5101 } | |
5102 | |
5103 // Done. | |
5104 set_memory(mem, adr_type); | |
5105 } | |
5106 | |
5107 | |
5108 bool | |
5109 LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type, | |
5110 BasicType basic_elem_type, | |
5111 AllocateNode* alloc, | |
5112 Node* src, Node* src_offset, | |
5113 Node* dest, Node* dest_offset, | |
5114 Node* dest_size) { | |
5115 // 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
|
5116 int scale = exact_log2(type2aelembytes(basic_elem_type)); |
0 | 5117 if (scale >= LogBytesPerLong) |
5118 return false; // it is already a block transfer | |
5119 | |
5120 // Look at the alignment of the starting offsets. | |
5121 int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); | |
5122 const intptr_t BIG_NEG = -128; | |
5123 assert(BIG_NEG + 2*abase < 0, "neg enough"); | |
5124 | |
5125 intptr_t src_off = abase + ((intptr_t) find_int_con(src_offset, -1) << scale); | |
5126 intptr_t dest_off = abase + ((intptr_t) find_int_con(dest_offset, -1) << scale); | |
5127 if (src_off < 0 || dest_off < 0) | |
5128 // At present, we can only understand constants. | |
5129 return false; | |
5130 | |
5131 if (((src_off | dest_off) & (BytesPerLong-1)) != 0) { | |
5132 // Non-aligned; too bad. | |
5133 // One more chance: Pick off an initial 32-bit word. | |
5134 // This is a common case, since abase can be odd mod 8. | |
5135 if (((src_off | dest_off) & (BytesPerLong-1)) == BytesPerInt && | |
5136 ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) { | |
5137 Node* sptr = basic_plus_adr(src, src_off); | |
5138 Node* dptr = basic_plus_adr(dest, dest_off); | |
5139 Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type); | |
5140 store_to_memory(control(), dptr, sval, T_INT, adr_type); | |
5141 src_off += BytesPerInt; | |
5142 dest_off += BytesPerInt; | |
5143 } else { | |
5144 return false; | |
5145 } | |
5146 } | |
5147 assert(src_off % BytesPerLong == 0, ""); | |
5148 assert(dest_off % BytesPerLong == 0, ""); | |
5149 | |
5150 // Do this copy by giant steps. | |
5151 Node* sptr = basic_plus_adr(src, src_off); | |
5152 Node* dptr = basic_plus_adr(dest, dest_off); | |
5153 Node* countx = dest_size; | |
5154 countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(dest_off)) ); | |
5155 countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong)) ); | |
5156 | |
5157 bool disjoint_bases = true; // since alloc != NULL | |
5158 generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases, | |
5159 sptr, NULL, dptr, NULL, countx); | |
5160 | |
5161 return true; | |
5162 } | |
5163 | |
5164 | |
5165 // Helper function; generates code for the slow case. | |
5166 // We make a call to a runtime method which emulates the native method, | |
5167 // but without the native wrapper overhead. | |
5168 void | |
5169 LibraryCallKit::generate_slow_arraycopy(const TypePtr* adr_type, | |
5170 Node* src, Node* src_offset, | |
5171 Node* dest, Node* dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
5172 Node* copy_length) { |
0 | 5173 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON, |
5174 OptoRuntime::slow_arraycopy_Type(), | |
5175 OptoRuntime::slow_arraycopy_Java(), | |
5176 "slow_arraycopy", adr_type, | |
5177 src, src_offset, dest, dest_offset, | |
5178 copy_length); | |
5179 | |
5180 // Handle exceptions thrown by this fellow: | |
5181 make_slow_call_ex(call, env()->Throwable_klass(), false); | |
5182 } | |
5183 | |
5184 // Helper function; generates code for cases requiring runtime checks. | |
5185 Node* | |
5186 LibraryCallKit::generate_checkcast_arraycopy(const TypePtr* adr_type, | |
5187 Node* dest_elem_klass, | |
5188 Node* src, Node* src_offset, | |
5189 Node* dest, Node* dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
5190 Node* copy_length) { |
0 | 5191 if (stopped()) return NULL; |
5192 | |
5193 address copyfunc_addr = StubRoutines::checkcast_arraycopy(); | |
5194 if (copyfunc_addr == NULL) { // Stub was not generated, go slow path. | |
5195 return NULL; | |
5196 } | |
5197 | |
5198 // Pick out the parameters required to perform a store-check | |
5199 // for the target array. This is an optimistic check. It will | |
5200 // look in each non-null element's class, at the desired klass's | |
5201 // super_check_offset, for the desired klass. | |
5202 int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc); | |
5203 Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); | |
1609 | 5204 Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr()); |
0 | 5205 Node* check_offset = _gvn.transform(n3); |
5206 Node* check_value = dest_elem_klass; | |
5207 | |
5208 Node* src_start = array_element_address(src, src_offset, T_OBJECT); | |
5209 Node* dest_start = array_element_address(dest, dest_offset, T_OBJECT); | |
5210 | |
5211 // (We know the arrays are never conjoint, because their types differ.) | |
5212 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, | |
5213 OptoRuntime::checkcast_arraycopy_Type(), | |
5214 copyfunc_addr, "checkcast_arraycopy", adr_type, | |
5215 // five arguments, of which two are | |
5216 // intptr_t (jlong in LP64) | |
5217 src_start, dest_start, | |
5218 copy_length XTOP, | |
5219 check_offset XTOP, | |
5220 check_value); | |
5221 | |
5222 return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms)); | |
5223 } | |
5224 | |
5225 | |
5226 // Helper function; generates code for cases requiring runtime checks. | |
5227 Node* | |
5228 LibraryCallKit::generate_generic_arraycopy(const TypePtr* adr_type, | |
5229 Node* src, Node* src_offset, | |
5230 Node* dest, Node* dest_offset, | |
833
acba6af809c8
6840775: Multiple JVM crashes seen with 1.6.0_10 through 1.6.0_14
kvn
parents:
827
diff
changeset
|
5231 Node* copy_length) { |
0 | 5232 if (stopped()) return NULL; |
5233 | |
5234 address copyfunc_addr = StubRoutines::generic_arraycopy(); | |
5235 if (copyfunc_addr == NULL) { // Stub was not generated, go slow path. | |
5236 return NULL; | |
5237 } | |
5238 | |
5239 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, | |
5240 OptoRuntime::generic_arraycopy_Type(), | |
5241 copyfunc_addr, "generic_arraycopy", adr_type, | |
5242 src, src_offset, dest, dest_offset, copy_length); | |
5243 | |
5244 return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms)); | |
5245 } | |
5246 | |
5247 // Helper function; generates the fast out-of-line call to an arraycopy stub. | |
5248 void | |
5249 LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type, | |
5250 BasicType basic_elem_type, | |
5251 bool disjoint_bases, | |
5252 Node* src, Node* src_offset, | |
5253 Node* dest, Node* dest_offset, | |
5254 Node* copy_length) { | |
5255 if (stopped()) return; // nothing to do | |
5256 | |
5257 Node* src_start = src; | |
5258 Node* dest_start = dest; | |
5259 if (src_offset != NULL || dest_offset != NULL) { | |
5260 assert(src_offset != NULL && dest_offset != NULL, ""); | |
5261 src_start = array_element_address(src, src_offset, basic_elem_type); | |
5262 dest_start = array_element_address(dest, dest_offset, basic_elem_type); | |
5263 } | |
5264 | |
5265 // Figure out which arraycopy runtime method to call. | |
5266 const char* copyfunc_name = "arraycopy"; | |
5267 address copyfunc_addr = | |
5268 basictype2arraycopy(basic_elem_type, src_offset, dest_offset, | |
5269 disjoint_bases, copyfunc_name); | |
5270 | |
5271 // Call it. Note that the count_ix value is not scaled to a byte-size. | |
5272 make_runtime_call(RC_LEAF|RC_NO_FP, | |
5273 OptoRuntime::fast_arraycopy_Type(), | |
5274 copyfunc_addr, copyfunc_name, adr_type, | |
5275 src_start, dest_start, copy_length XTOP); | |
5276 } |