1/*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "jvm.h"
27#include "classfile/symbolTable.hpp"
28#include "classfile/vmSymbols.hpp"
29#include "compiler/compilerDirectives.hpp"
30#include "memory/allocation.inline.hpp"
31#include "memory/oopFactory.hpp"
32#include "memory/metaspaceClosure.hpp"
33#include "oops/oop.inline.hpp"
34#include "runtime/handles.inline.hpp"
35#include "utilities/xmlstream.hpp"
36
37
38Symbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT];
39
40Symbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ };
41
42inline int compare_symbol(const Symbol* a, const Symbol* b) {
43 if (a == b) return 0;
44 // follow the natural address order:
45 return (address)a > (address)b ? +1 : -1;
46}
47
48static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT];
49extern "C" {
50 static int compare_vmsymbol_sid(const void* void_a, const void* void_b) {
51 const Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a));
52 const Symbol* b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b));
53 return compare_symbol(a, b);
54 }
55}
56
57#ifdef ASSERT
58#define VM_SYMBOL_ENUM_NAME_BODY(name, string) #name "\0"
59static const char* vm_symbol_enum_names =
60 VM_SYMBOLS_DO(VM_SYMBOL_ENUM_NAME_BODY, VM_ALIAS_IGNORE)
61 "\0";
62static const char* vm_symbol_enum_name(vmSymbols::SID sid) {
63 const char* string = &vm_symbol_enum_names[0];
64 int skip = (int)sid - (int)vmSymbols::FIRST_SID;
65 for (; skip != 0; skip--) {
66 size_t skiplen = strlen(string);
67 if (skiplen == 0) return "<unknown>"; // overflow
68 string += skiplen+1;
69 }
70 return string;
71}
72#endif //ASSERT
73
74// Put all the VM symbol strings in one place.
75// Makes for a more compact libjvm.
76#define VM_SYMBOL_BODY(name, string) string "\0"
77static const char* vm_symbol_bodies = VM_SYMBOLS_DO(VM_SYMBOL_BODY, VM_ALIAS_IGNORE);
78
79void vmSymbols::initialize(TRAPS) {
80 assert((int)SID_LIMIT <= (1<<log2_SID_LIMIT), "must fit in this bitfield");
81 assert((int)SID_LIMIT*5 > (1<<log2_SID_LIMIT), "make the bitfield smaller, please");
82 assert(vmIntrinsics::FLAG_LIMIT <= (1 << vmIntrinsics::log2_FLAG_LIMIT), "must fit in this bitfield");
83
84 if (!UseSharedSpaces) {
85 const char* string = &vm_symbol_bodies[0];
86 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
87 Symbol* sym = SymbolTable::new_permanent_symbol(string);
88 _symbols[index] = sym;
89 string += strlen(string); // skip string body
90 string += 1; // skip trailing null
91 }
92
93 _type_signatures[T_BYTE] = byte_signature();
94 _type_signatures[T_CHAR] = char_signature();
95 _type_signatures[T_DOUBLE] = double_signature();
96 _type_signatures[T_FLOAT] = float_signature();
97 _type_signatures[T_INT] = int_signature();
98 _type_signatures[T_LONG] = long_signature();
99 _type_signatures[T_SHORT] = short_signature();
100 _type_signatures[T_BOOLEAN] = bool_signature();
101 _type_signatures[T_VOID] = void_signature();
102 // no single signatures for T_OBJECT or T_ARRAY
103#ifdef ASSERT
104 for (int i = (int)T_BOOLEAN; i < (int)T_VOID+1; i++) {
105 Symbol* s = _type_signatures[i];
106 if (s == NULL) continue;
107 BasicType st = signature_type(s);
108 assert(st == i, "");
109 }
110#endif
111 }
112
113#ifdef ASSERT
114 // Check for duplicates:
115 for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) {
116 Symbol* sym = symbol_at((SID)i1);
117 for (int i2 = (int)FIRST_SID; i2 < i1; i2++) {
118 if (symbol_at((SID)i2) == sym) {
119 tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"",
120 vm_symbol_enum_name((SID)i2), i2,
121 vm_symbol_enum_name((SID)i1), i1);
122 sym->print_symbol_on(tty);
123 tty->print_cr("\"");
124 }
125 }
126 }
127#endif //ASSERT
128
129 // Create an index for find_id:
130 {
131 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
132 vm_symbol_index[index] = (SID)index;
133 }
134 int num_sids = SID_LIMIT-FIRST_SID;
135 qsort(&vm_symbol_index[FIRST_SID], num_sids, sizeof(vm_symbol_index[0]),
136 compare_vmsymbol_sid);
137 }
138
139#ifdef ASSERT
140 {
141 // Spot-check correspondence between strings, symbols, and enums:
142 assert(_symbols[NO_SID] == NULL, "must be");
143 const char* str = "java/lang/Object";
144 TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str);
145 assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
146 assert(jlo == java_lang_Object(), "");
147 SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
148 assert(find_sid(jlo) == sid, "");
149 assert(symbol_at(sid) == jlo, "");
150
151 // Make sure find_sid produces the right answer in each case.
152 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
153 Symbol* sym = symbol_at((SID)index);
154 sid = find_sid(sym);
155 assert(sid == (SID)index, "symbol index works");
156 // Note: If there are duplicates, this assert will fail.
157 // A "Duplicate VM symbol" message will have already been printed.
158 }
159
160 // The string "format" happens (at the moment) not to be a vmSymbol,
161 // though it is a method name in java.lang.String.
162 str = "format";
163 TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str);
164 sid = find_sid(fmt);
165 assert(sid == NO_SID, "symbol index works (negative test)");
166 }
167#endif
168}
169
170
171#ifndef PRODUCT
172const char* vmSymbols::name_for(vmSymbols::SID sid) {
173 if (sid == NO_SID)
174 return "NO_SID";
175 const char* string = &vm_symbol_bodies[0];
176 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
177 if (index == (int)sid)
178 return string;
179 string += strlen(string); // skip string body
180 string += 1; // skip trailing null
181 }
182 return "BAD_SID";
183}
184#endif
185
186
187
188void vmSymbols::symbols_do(SymbolClosure* f) {
189 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
190 f->do_symbol(&_symbols[index]);
191 }
192 for (int i = 0; i < T_VOID+1; i++) {
193 f->do_symbol(&_type_signatures[i]);
194 }
195}
196
197void vmSymbols::metaspace_pointers_do(MetaspaceClosure *it) {
198 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
199 it->push(&_symbols[index]);
200 }
201 for (int i = 0; i < T_VOID+1; i++) {
202 it->push(&_type_signatures[i]);
203 }
204}
205
206void vmSymbols::serialize(SerializeClosure* soc) {
207 soc->do_region((u_char*)&_symbols[FIRST_SID],
208 (SID_LIMIT - FIRST_SID) * sizeof(_symbols[0]));
209 soc->do_region((u_char*)_type_signatures, sizeof(_type_signatures));
210}
211
212
213BasicType vmSymbols::signature_type(const Symbol* s) {
214 assert(s != NULL, "checking");
215 if (s->utf8_length() == 1) {
216 BasicType result = char2type(s->char_at(0));
217 if (is_java_primitive(result) || result == T_VOID) {
218 assert(s == _type_signatures[result], "");
219 return result;
220 }
221 }
222 return T_OBJECT;
223}
224
225
226static int mid_hint = (int)vmSymbols::FIRST_SID+1;
227
228#ifndef PRODUCT
229static int find_sid_calls, find_sid_probes;
230// (Typical counts are calls=7000 and probes=17000.)
231#endif
232
233vmSymbols::SID vmSymbols::find_sid(const Symbol* symbol) {
234 // Handle the majority of misses by a bounds check.
235 // Then, use a binary search over the index.
236 // Expected trip count is less than log2_SID_LIMIT, about eight.
237 // This is slow but acceptable, given that calls are not
238 // dynamically common. (Method*::intrinsic_id has a cache.)
239 NOT_PRODUCT(find_sid_calls++);
240 int min = (int)FIRST_SID, max = (int)SID_LIMIT - 1;
241 SID sid = NO_SID, sid1;
242 int cmp1;
243 sid1 = vm_symbol_index[min];
244 cmp1 = compare_symbol(symbol, symbol_at(sid1));
245 if (cmp1 <= 0) { // before the first
246 if (cmp1 == 0) sid = sid1;
247 } else {
248 sid1 = vm_symbol_index[max];
249 cmp1 = compare_symbol(symbol, symbol_at(sid1));
250 if (cmp1 >= 0) { // after the last
251 if (cmp1 == 0) sid = sid1;
252 } else {
253 // After checking the extremes, do a binary search.
254 ++min; --max; // endpoints are done
255 int mid = mid_hint; // start at previous success
256 while (max >= min) {
257 assert(mid >= min && mid <= max, "");
258 NOT_PRODUCT(find_sid_probes++);
259 sid1 = vm_symbol_index[mid];
260 cmp1 = compare_symbol(symbol, symbol_at(sid1));
261 if (cmp1 == 0) {
262 mid_hint = mid;
263 sid = sid1;
264 break;
265 }
266 if (cmp1 < 0)
267 max = mid - 1; // symbol < symbol_at(sid)
268 else
269 min = mid + 1;
270
271 // Pick a new probe point:
272 mid = (max + min) / 2;
273 }
274 }
275 }
276
277#ifdef ASSERT
278 // Perform the exhaustive self-check the first 1000 calls,
279 // and every 100 calls thereafter.
280 static int find_sid_check_count = -2000;
281 if ((uint)++find_sid_check_count > (uint)100) {
282 if (find_sid_check_count > 0) find_sid_check_count = 0;
283
284 // Make sure this is the right answer, using linear search.
285 // (We have already proven that there are no duplicates in the list.)
286 SID sid2 = NO_SID;
287 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
288 Symbol* sym2 = symbol_at((SID)index);
289 if (sym2 == symbol) {
290 sid2 = (SID)index;
291 break;
292 }
293 }
294 // Unless it's a duplicate, assert that the sids are the same.
295 if (_symbols[sid] != _symbols[sid2]) {
296 assert(sid == sid2, "binary same as linear search");
297 }
298 }
299#endif //ASSERT
300
301 return sid;
302}
303
304vmSymbols::SID vmSymbols::find_sid(const char* symbol_name) {
305 Symbol* symbol = SymbolTable::probe(symbol_name, (int) strlen(symbol_name));
306 if (symbol == NULL) return NO_SID;
307 return find_sid(symbol);
308}
309
310static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
311#define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
312 switch (TYPE2(type, unboxing)) {
313#define BASIC_TYPE_CASE(type, box, unbox) \
314 case TYPE2(type, false): return vmIntrinsics::box; \
315 case TYPE2(type, true): return vmIntrinsics::unbox
316 BASIC_TYPE_CASE(T_BOOLEAN, _Boolean_valueOf, _booleanValue);
317 BASIC_TYPE_CASE(T_BYTE, _Byte_valueOf, _byteValue);
318 BASIC_TYPE_CASE(T_CHAR, _Character_valueOf, _charValue);
319 BASIC_TYPE_CASE(T_SHORT, _Short_valueOf, _shortValue);
320 BASIC_TYPE_CASE(T_INT, _Integer_valueOf, _intValue);
321 BASIC_TYPE_CASE(T_LONG, _Long_valueOf, _longValue);
322 BASIC_TYPE_CASE(T_FLOAT, _Float_valueOf, _floatValue);
323 BASIC_TYPE_CASE(T_DOUBLE, _Double_valueOf, _doubleValue);
324#undef BASIC_TYPE_CASE
325 }
326#undef TYPE2
327 return vmIntrinsics::_none;
328}
329
330vmIntrinsics::ID vmIntrinsics::for_boxing(BasicType type) {
331 return wrapper_intrinsic(type, false);
332}
333vmIntrinsics::ID vmIntrinsics::for_unboxing(BasicType type) {
334 return wrapper_intrinsic(type, true);
335}
336
337vmIntrinsics::ID vmIntrinsics::for_raw_conversion(BasicType src, BasicType dest) {
338#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d))
339 switch (SRC_DEST(src, dest)) {
340 case SRC_DEST(T_INT, T_FLOAT): return vmIntrinsics::_intBitsToFloat;
341 case SRC_DEST(T_FLOAT, T_INT): return vmIntrinsics::_floatToRawIntBits;
342
343 case SRC_DEST(T_LONG, T_DOUBLE): return vmIntrinsics::_longBitsToDouble;
344 case SRC_DEST(T_DOUBLE, T_LONG): return vmIntrinsics::_doubleToRawLongBits;
345 }
346#undef SRC_DEST
347
348 return vmIntrinsics::_none;
349}
350
351bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
352 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
353 switch(id) {
354#ifdef JFR_HAVE_INTRINSICS
355 case vmIntrinsics::_counterTime:
356#endif
357 case vmIntrinsics::_currentTimeMillis:
358 case vmIntrinsics::_nanoTime:
359 case vmIntrinsics::_floatToRawIntBits:
360 case vmIntrinsics::_intBitsToFloat:
361 case vmIntrinsics::_doubleToRawLongBits:
362 case vmIntrinsics::_longBitsToDouble:
363 case vmIntrinsics::_getClass:
364 case vmIntrinsics::_isInstance:
365 case vmIntrinsics::_currentThread:
366 case vmIntrinsics::_dabs:
367 case vmIntrinsics::_fabs:
368 case vmIntrinsics::_iabs:
369 case vmIntrinsics::_labs:
370 case vmIntrinsics::_dsqrt:
371 case vmIntrinsics::_dsin:
372 case vmIntrinsics::_dcos:
373 case vmIntrinsics::_dtan:
374 case vmIntrinsics::_dlog:
375 case vmIntrinsics::_dlog10:
376 case vmIntrinsics::_dexp:
377 case vmIntrinsics::_dpow:
378 case vmIntrinsics::_checkIndex:
379 case vmIntrinsics::_Reference_get:
380 case vmIntrinsics::_updateCRC32:
381 case vmIntrinsics::_updateBytesCRC32:
382 case vmIntrinsics::_updateByteBufferCRC32:
383 case vmIntrinsics::_vectorizedMismatch:
384 case vmIntrinsics::_fmaD:
385 case vmIntrinsics::_fmaF:
386 case vmIntrinsics::_isDigit:
387 case vmIntrinsics::_isLowerCase:
388 case vmIntrinsics::_isUpperCase:
389 case vmIntrinsics::_isWhitespace:
390 return true;
391 default:
392 return false;
393 }
394}
395
396bool vmIntrinsics::can_trap(vmIntrinsics::ID id) {
397 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
398 switch(id) {
399#ifdef JFR_HAVE_INTRINSICS
400 case vmIntrinsics::_counterTime:
401 case vmIntrinsics::_getClassId:
402#endif
403 case vmIntrinsics::_currentTimeMillis:
404 case vmIntrinsics::_nanoTime:
405 case vmIntrinsics::_floatToRawIntBits:
406 case vmIntrinsics::_intBitsToFloat:
407 case vmIntrinsics::_doubleToRawLongBits:
408 case vmIntrinsics::_longBitsToDouble:
409 case vmIntrinsics::_currentThread:
410 case vmIntrinsics::_dabs:
411 case vmIntrinsics::_fabs:
412 case vmIntrinsics::_iabs:
413 case vmIntrinsics::_labs:
414 case vmIntrinsics::_dsqrt:
415 case vmIntrinsics::_dsin:
416 case vmIntrinsics::_dcos:
417 case vmIntrinsics::_dtan:
418 case vmIntrinsics::_dlog:
419 case vmIntrinsics::_dlog10:
420 case vmIntrinsics::_dexp:
421 case vmIntrinsics::_dpow:
422 case vmIntrinsics::_updateCRC32:
423 case vmIntrinsics::_updateBytesCRC32:
424 case vmIntrinsics::_updateByteBufferCRC32:
425 case vmIntrinsics::_vectorizedMismatch:
426 case vmIntrinsics::_fmaD:
427 case vmIntrinsics::_fmaF:
428 return false;
429 default:
430 return true;
431 }
432}
433
434// Some intrinsics produce different results if they are not pinned
435bool vmIntrinsics::should_be_pinned(vmIntrinsics::ID id) {
436 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
437 switch(id) {
438#ifdef JFR_HAVE_INTRINSICS
439 case vmIntrinsics::_counterTime:
440#endif
441 case vmIntrinsics::_currentTimeMillis:
442 case vmIntrinsics::_nanoTime:
443 return true;
444 default:
445 return false;
446 }
447}
448
449bool vmIntrinsics::does_virtual_dispatch(vmIntrinsics::ID id) {
450 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
451 switch(id) {
452 case vmIntrinsics::_hashCode:
453 case vmIntrinsics::_clone:
454 return true;
455 break;
456 default:
457 return false;
458 }
459}
460
461int vmIntrinsics::predicates_needed(vmIntrinsics::ID id) {
462 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
463 switch (id) {
464 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
465 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
466 case vmIntrinsics::_counterMode_AESCrypt:
467 return 1;
468 case vmIntrinsics::_digestBase_implCompressMB:
469 return 3;
470 default:
471 return 0;
472 }
473}
474
475bool vmIntrinsics::is_intrinsic_available(vmIntrinsics::ID id) {
476 return !vmIntrinsics::is_intrinsic_disabled(id) &&
477 !vmIntrinsics::is_disabled_by_flags(id);
478}
479
480bool vmIntrinsics::is_intrinsic_disabled(vmIntrinsics::ID id) {
481 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
482
483 // Canonicalize DisableIntrinsic to contain only ',' as a separator.
484 // Note, DirectiveSet may not be created at this point yet since this code
485 // is called from initial stub geenration code.
486 char* local_list = (char*)DirectiveSet::canonicalize_disableintrinsic(DisableIntrinsic);
487 char* save_ptr;
488 bool found = false;
489
490 char* token = strtok_r(local_list, ",", &save_ptr);
491 while (token != NULL) {
492 if (strcmp(token, vmIntrinsics::name_at(id)) == 0) {
493 found = true;
494 break;
495 } else {
496 token = strtok_r(NULL, ",", &save_ptr);
497 }
498 }
499
500 FREE_C_HEAP_ARRAY(char, local_list);
501 return found;
502}
503
504
505bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
506 vmIntrinsics::ID id = method->intrinsic_id();
507 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
508 return is_disabled_by_flags(id);
509}
510
511bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
512 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
513
514 // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in
515 // the following switch statement.
516 if (!InlineNatives) {
517 switch (id) {
518 case vmIntrinsics::_indexOfL:
519 case vmIntrinsics::_indexOfU:
520 case vmIntrinsics::_indexOfUL:
521 case vmIntrinsics::_indexOfIL:
522 case vmIntrinsics::_indexOfIU:
523 case vmIntrinsics::_indexOfIUL:
524 case vmIntrinsics::_indexOfU_char:
525 case vmIntrinsics::_compareToL:
526 case vmIntrinsics::_compareToU:
527 case vmIntrinsics::_compareToLU:
528 case vmIntrinsics::_compareToUL:
529 case vmIntrinsics::_equalsL:
530 case vmIntrinsics::_equalsU:
531 case vmIntrinsics::_equalsC:
532 case vmIntrinsics::_getCharStringU:
533 case vmIntrinsics::_putCharStringU:
534 case vmIntrinsics::_compressStringC:
535 case vmIntrinsics::_compressStringB:
536 case vmIntrinsics::_inflateStringC:
537 case vmIntrinsics::_inflateStringB:
538 case vmIntrinsics::_getAndAddInt:
539 case vmIntrinsics::_getAndAddLong:
540 case vmIntrinsics::_getAndSetInt:
541 case vmIntrinsics::_getAndSetLong:
542 case vmIntrinsics::_getAndSetReference:
543 case vmIntrinsics::_loadFence:
544 case vmIntrinsics::_storeFence:
545 case vmIntrinsics::_fullFence:
546 case vmIntrinsics::_hasNegatives:
547 case vmIntrinsics::_Reference_get:
548 break;
549 default:
550 return true;
551 }
552 }
553
554 switch (id) {
555 case vmIntrinsics::_isInstance:
556 case vmIntrinsics::_isAssignableFrom:
557 case vmIntrinsics::_getModifiers:
558 case vmIntrinsics::_isInterface:
559 case vmIntrinsics::_isArray:
560 case vmIntrinsics::_isPrimitive:
561 case vmIntrinsics::_getSuperclass:
562 case vmIntrinsics::_Class_cast:
563 case vmIntrinsics::_getLength:
564 case vmIntrinsics::_newArray:
565 case vmIntrinsics::_getClass:
566 if (!InlineClassNatives) return true;
567 break;
568 case vmIntrinsics::_currentThread:
569 case vmIntrinsics::_isInterrupted:
570 if (!InlineThreadNatives) return true;
571 break;
572 case vmIntrinsics::_floatToRawIntBits:
573 case vmIntrinsics::_intBitsToFloat:
574 case vmIntrinsics::_doubleToRawLongBits:
575 case vmIntrinsics::_longBitsToDouble:
576 case vmIntrinsics::_dabs:
577 case vmIntrinsics::_fabs:
578 case vmIntrinsics::_iabs:
579 case vmIntrinsics::_labs:
580 case vmIntrinsics::_dsqrt:
581 case vmIntrinsics::_dsin:
582 case vmIntrinsics::_dcos:
583 case vmIntrinsics::_dtan:
584 case vmIntrinsics::_dlog:
585 case vmIntrinsics::_dexp:
586 case vmIntrinsics::_dpow:
587 case vmIntrinsics::_dlog10:
588 case vmIntrinsics::_datan2:
589 case vmIntrinsics::_min:
590 case vmIntrinsics::_max:
591 case vmIntrinsics::_floatToIntBits:
592 case vmIntrinsics::_doubleToLongBits:
593 case vmIntrinsics::_maxF:
594 case vmIntrinsics::_minF:
595 case vmIntrinsics::_maxD:
596 case vmIntrinsics::_minD:
597 if (!InlineMathNatives) return true;
598 break;
599 case vmIntrinsics::_fmaD:
600 case vmIntrinsics::_fmaF:
601 if (!InlineMathNatives || !UseFMA) return true;
602 break;
603 case vmIntrinsics::_arraycopy:
604 if (!InlineArrayCopy) return true;
605 break;
606 case vmIntrinsics::_updateCRC32:
607 case vmIntrinsics::_updateBytesCRC32:
608 case vmIntrinsics::_updateByteBufferCRC32:
609 if (!UseCRC32Intrinsics) return true;
610 break;
611 case vmIntrinsics::_getReference:
612 case vmIntrinsics::_getBoolean:
613 case vmIntrinsics::_getByte:
614 case vmIntrinsics::_getShort:
615 case vmIntrinsics::_getChar:
616 case vmIntrinsics::_getInt:
617 case vmIntrinsics::_getLong:
618 case vmIntrinsics::_getFloat:
619 case vmIntrinsics::_getDouble:
620 case vmIntrinsics::_putReference:
621 case vmIntrinsics::_putBoolean:
622 case vmIntrinsics::_putByte:
623 case vmIntrinsics::_putShort:
624 case vmIntrinsics::_putChar:
625 case vmIntrinsics::_putInt:
626 case vmIntrinsics::_putLong:
627 case vmIntrinsics::_putFloat:
628 case vmIntrinsics::_putDouble:
629 case vmIntrinsics::_getReferenceVolatile:
630 case vmIntrinsics::_getBooleanVolatile:
631 case vmIntrinsics::_getByteVolatile:
632 case vmIntrinsics::_getShortVolatile:
633 case vmIntrinsics::_getCharVolatile:
634 case vmIntrinsics::_getIntVolatile:
635 case vmIntrinsics::_getLongVolatile:
636 case vmIntrinsics::_getFloatVolatile:
637 case vmIntrinsics::_getDoubleVolatile:
638 case vmIntrinsics::_putReferenceVolatile:
639 case vmIntrinsics::_putBooleanVolatile:
640 case vmIntrinsics::_putByteVolatile:
641 case vmIntrinsics::_putShortVolatile:
642 case vmIntrinsics::_putCharVolatile:
643 case vmIntrinsics::_putIntVolatile:
644 case vmIntrinsics::_putLongVolatile:
645 case vmIntrinsics::_putFloatVolatile:
646 case vmIntrinsics::_putDoubleVolatile:
647 case vmIntrinsics::_getReferenceAcquire:
648 case vmIntrinsics::_getBooleanAcquire:
649 case vmIntrinsics::_getByteAcquire:
650 case vmIntrinsics::_getShortAcquire:
651 case vmIntrinsics::_getCharAcquire:
652 case vmIntrinsics::_getIntAcquire:
653 case vmIntrinsics::_getLongAcquire:
654 case vmIntrinsics::_getFloatAcquire:
655 case vmIntrinsics::_getDoubleAcquire:
656 case vmIntrinsics::_putReferenceRelease:
657 case vmIntrinsics::_putBooleanRelease:
658 case vmIntrinsics::_putByteRelease:
659 case vmIntrinsics::_putShortRelease:
660 case vmIntrinsics::_putCharRelease:
661 case vmIntrinsics::_putIntRelease:
662 case vmIntrinsics::_putLongRelease:
663 case vmIntrinsics::_putFloatRelease:
664 case vmIntrinsics::_putDoubleRelease:
665 case vmIntrinsics::_getReferenceOpaque:
666 case vmIntrinsics::_getBooleanOpaque:
667 case vmIntrinsics::_getByteOpaque:
668 case vmIntrinsics::_getShortOpaque:
669 case vmIntrinsics::_getCharOpaque:
670 case vmIntrinsics::_getIntOpaque:
671 case vmIntrinsics::_getLongOpaque:
672 case vmIntrinsics::_getFloatOpaque:
673 case vmIntrinsics::_getDoubleOpaque:
674 case vmIntrinsics::_putReferenceOpaque:
675 case vmIntrinsics::_putBooleanOpaque:
676 case vmIntrinsics::_putByteOpaque:
677 case vmIntrinsics::_putShortOpaque:
678 case vmIntrinsics::_putCharOpaque:
679 case vmIntrinsics::_putIntOpaque:
680 case vmIntrinsics::_putLongOpaque:
681 case vmIntrinsics::_putFloatOpaque:
682 case vmIntrinsics::_putDoubleOpaque:
683 case vmIntrinsics::_getAndAddInt:
684 case vmIntrinsics::_getAndAddLong:
685 case vmIntrinsics::_getAndSetInt:
686 case vmIntrinsics::_getAndSetLong:
687 case vmIntrinsics::_getAndSetReference:
688 case vmIntrinsics::_loadFence:
689 case vmIntrinsics::_storeFence:
690 case vmIntrinsics::_fullFence:
691 case vmIntrinsics::_compareAndSetLong:
692 case vmIntrinsics::_weakCompareAndSetLong:
693 case vmIntrinsics::_weakCompareAndSetLongPlain:
694 case vmIntrinsics::_weakCompareAndSetLongAcquire:
695 case vmIntrinsics::_weakCompareAndSetLongRelease:
696 case vmIntrinsics::_compareAndSetInt:
697 case vmIntrinsics::_weakCompareAndSetInt:
698 case vmIntrinsics::_weakCompareAndSetIntPlain:
699 case vmIntrinsics::_weakCompareAndSetIntAcquire:
700 case vmIntrinsics::_weakCompareAndSetIntRelease:
701 case vmIntrinsics::_compareAndSetReference:
702 case vmIntrinsics::_weakCompareAndSetReference:
703 case vmIntrinsics::_weakCompareAndSetReferencePlain:
704 case vmIntrinsics::_weakCompareAndSetReferenceAcquire:
705 case vmIntrinsics::_weakCompareAndSetReferenceRelease:
706 case vmIntrinsics::_compareAndExchangeInt:
707 case vmIntrinsics::_compareAndExchangeIntAcquire:
708 case vmIntrinsics::_compareAndExchangeIntRelease:
709 case vmIntrinsics::_compareAndExchangeLong:
710 case vmIntrinsics::_compareAndExchangeLongAcquire:
711 case vmIntrinsics::_compareAndExchangeLongRelease:
712 case vmIntrinsics::_compareAndExchangeReference:
713 case vmIntrinsics::_compareAndExchangeReferenceAcquire:
714 case vmIntrinsics::_compareAndExchangeReferenceRelease:
715 if (!InlineUnsafeOps) return true;
716 break;
717 case vmIntrinsics::_getShortUnaligned:
718 case vmIntrinsics::_getCharUnaligned:
719 case vmIntrinsics::_getIntUnaligned:
720 case vmIntrinsics::_getLongUnaligned:
721 case vmIntrinsics::_putShortUnaligned:
722 case vmIntrinsics::_putCharUnaligned:
723 case vmIntrinsics::_putIntUnaligned:
724 case vmIntrinsics::_putLongUnaligned:
725 case vmIntrinsics::_allocateInstance:
726 if (!InlineUnsafeOps || !UseUnalignedAccesses) return true;
727 break;
728 case vmIntrinsics::_hashCode:
729 if (!InlineObjectHash) return true;
730 break;
731 case vmIntrinsics::_aescrypt_encryptBlock:
732 case vmIntrinsics::_aescrypt_decryptBlock:
733 if (!UseAESIntrinsics) return true;
734 break;
735 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
736 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
737 if (!UseAESIntrinsics) return true;
738 break;
739 case vmIntrinsics::_counterMode_AESCrypt:
740 if (!UseAESCTRIntrinsics) return true;
741 break;
742 case vmIntrinsics::_sha_implCompress:
743 if (!UseSHA1Intrinsics) return true;
744 break;
745 case vmIntrinsics::_sha2_implCompress:
746 if (!UseSHA256Intrinsics) return true;
747 break;
748 case vmIntrinsics::_sha5_implCompress:
749 if (!UseSHA512Intrinsics) return true;
750 break;
751 case vmIntrinsics::_digestBase_implCompressMB:
752 if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true;
753 break;
754 case vmIntrinsics::_ghash_processBlocks:
755 if (!UseGHASHIntrinsics) return true;
756 break;
757 case vmIntrinsics::_base64_encodeBlock:
758 if (!UseBASE64Intrinsics) return true;
759 break;
760 case vmIntrinsics::_updateBytesCRC32C:
761 case vmIntrinsics::_updateDirectByteBufferCRC32C:
762 if (!UseCRC32CIntrinsics) return true;
763 break;
764 case vmIntrinsics::_vectorizedMismatch:
765 if (!UseVectorizedMismatchIntrinsic) return true;
766 break;
767 case vmIntrinsics::_updateBytesAdler32:
768 case vmIntrinsics::_updateByteBufferAdler32:
769 if (!UseAdler32Intrinsics) return true;
770 break;
771 case vmIntrinsics::_copyMemory:
772 if (!InlineArrayCopy || !InlineUnsafeOps) return true;
773 break;
774#ifdef COMPILER1
775 case vmIntrinsics::_checkIndex:
776 if (!InlineNIOCheckIndex) return true;
777 break;
778#endif // COMPILER1
779#ifdef COMPILER2
780 case vmIntrinsics::_clone:
781#if INCLUDE_ZGC
782 if (UseZGC) return true;
783#endif
784 case vmIntrinsics::_copyOf:
785 case vmIntrinsics::_copyOfRange:
786 // These intrinsics use both the objectcopy and the arraycopy
787 // intrinsic mechanism.
788 if (!InlineObjectCopy || !InlineArrayCopy) return true;
789 break;
790 case vmIntrinsics::_compareToL:
791 case vmIntrinsics::_compareToU:
792 case vmIntrinsics::_compareToLU:
793 case vmIntrinsics::_compareToUL:
794 if (!SpecialStringCompareTo) return true;
795 break;
796 case vmIntrinsics::_indexOfL:
797 case vmIntrinsics::_indexOfU:
798 case vmIntrinsics::_indexOfUL:
799 case vmIntrinsics::_indexOfIL:
800 case vmIntrinsics::_indexOfIU:
801 case vmIntrinsics::_indexOfIUL:
802 case vmIntrinsics::_indexOfU_char:
803 if (!SpecialStringIndexOf) return true;
804 break;
805 case vmIntrinsics::_equalsL:
806 case vmIntrinsics::_equalsU:
807 if (!SpecialStringEquals) return true;
808 break;
809 case vmIntrinsics::_equalsB:
810 case vmIntrinsics::_equalsC:
811 if (!SpecialArraysEquals) return true;
812 break;
813 case vmIntrinsics::_encodeISOArray:
814 case vmIntrinsics::_encodeByteISOArray:
815 if (!SpecialEncodeISOArray) return true;
816 break;
817 case vmIntrinsics::_getCallerClass:
818 if (!InlineReflectionGetCallerClass) return true;
819 break;
820 case vmIntrinsics::_multiplyToLen:
821 if (!UseMultiplyToLenIntrinsic) return true;
822 break;
823 case vmIntrinsics::_squareToLen:
824 if (!UseSquareToLenIntrinsic) return true;
825 break;
826 case vmIntrinsics::_mulAdd:
827 if (!UseMulAddIntrinsic) return true;
828 break;
829 case vmIntrinsics::_montgomeryMultiply:
830 if (!UseMontgomeryMultiplyIntrinsic) return true;
831 break;
832 case vmIntrinsics::_montgomerySquare:
833 if (!UseMontgomerySquareIntrinsic) return true;
834 break;
835 case vmIntrinsics::_addExactI:
836 case vmIntrinsics::_addExactL:
837 case vmIntrinsics::_decrementExactI:
838 case vmIntrinsics::_decrementExactL:
839 case vmIntrinsics::_incrementExactI:
840 case vmIntrinsics::_incrementExactL:
841 case vmIntrinsics::_multiplyExactI:
842 case vmIntrinsics::_multiplyExactL:
843 case vmIntrinsics::_negateExactI:
844 case vmIntrinsics::_negateExactL:
845 case vmIntrinsics::_subtractExactI:
846 case vmIntrinsics::_subtractExactL:
847 if (!UseMathExactIntrinsics || !InlineMathNatives) return true;
848 break;
849 case vmIntrinsics::_isDigit:
850 case vmIntrinsics::_isLowerCase:
851 case vmIntrinsics::_isUpperCase:
852 case vmIntrinsics::_isWhitespace:
853 if (!UseCharacterCompareIntrinsics) return true;
854 break;
855#endif // COMPILER2
856 default:
857 return false;
858 }
859
860 return false;
861}
862
863#define VM_INTRINSIC_INITIALIZE(id, klass, name, sig, flags) #id "\0"
864static const char* vm_intrinsic_name_bodies =
865 VM_INTRINSICS_DO(VM_INTRINSIC_INITIALIZE,
866 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
867
868static const char* vm_intrinsic_name_table[vmIntrinsics::ID_LIMIT];
869
870const char* vmIntrinsics::name_at(vmIntrinsics::ID id) {
871 const char** nt = &vm_intrinsic_name_table[0];
872 if (nt[_none] == NULL) {
873 char* string = (char*) &vm_intrinsic_name_bodies[0];
874 for (int index = FIRST_ID; index < ID_LIMIT; index++) {
875 nt[index] = string;
876 string += strlen(string); // skip string body
877 string += 1; // skip trailing null
878 }
879 assert(!strcmp(nt[_hashCode], "_hashCode"), "lined up");
880 nt[_none] = "_none";
881 }
882 if ((uint)id < (uint)ID_LIMIT)
883 return vm_intrinsic_name_table[(uint)id];
884 else
885 return "(unknown intrinsic)";
886}
887
888// These are flag-matching functions:
889inline bool match_F_R(jshort flags) {
890 const int req = 0;
891 const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
892 return (flags & (req | neg)) == req;
893}
894inline bool match_F_Y(jshort flags) {
895 const int req = JVM_ACC_SYNCHRONIZED;
896 const int neg = JVM_ACC_STATIC;
897 return (flags & (req | neg)) == req;
898}
899inline bool match_F_RN(jshort flags) {
900 const int req = JVM_ACC_NATIVE;
901 const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
902 return (flags & (req | neg)) == req;
903}
904inline bool match_F_S(jshort flags) {
905 const int req = JVM_ACC_STATIC;
906 const int neg = JVM_ACC_SYNCHRONIZED;
907 return (flags & (req | neg)) == req;
908}
909inline bool match_F_SN(jshort flags) {
910 const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE;
911 const int neg = JVM_ACC_SYNCHRONIZED;
912 return (flags & (req | neg)) == req;
913}
914inline bool match_F_RNY(jshort flags) {
915 const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED;
916 const int neg = JVM_ACC_STATIC;
917 return (flags & (req | neg)) == req;
918}
919
920// These are for forming case labels:
921#define ID3(x, y, z) (( jlong)(z) + \
922 ((jlong)(y) << vmSymbols::log2_SID_LIMIT) + \
923 ((jlong)(x) << (2*vmSymbols::log2_SID_LIMIT)) )
924#define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
925
926vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbols::SID holder,
927 vmSymbols::SID name,
928 vmSymbols::SID sig,
929 jshort flags) {
930 assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit");
931
932 // Let the C compiler build the decision tree.
933
934#define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \
935 case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \
936 if (!match_##fcode(flags)) break; \
937 return id;
938
939 switch (ID3(holder, name, sig)) {
940 VM_INTRINSICS_DO(VM_INTRINSIC_CASE,
941 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
942 }
943 return vmIntrinsics::_none;
944
945#undef VM_INTRINSIC_CASE
946}
947
948
949const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) {
950 const char* str = name_at(id);
951#ifndef PRODUCT
952 const char* kname = vmSymbols::name_for(class_for(id));
953 const char* mname = vmSymbols::name_for(name_for(id));
954 const char* sname = vmSymbols::name_for(signature_for(id));
955 const char* fname = "";
956 switch (flags_for(id)) {
957 case F_Y: fname = "synchronized "; break;
958 case F_RN: fname = "native "; break;
959 case F_SN: fname = "native static "; break;
960 case F_S: fname = "static "; break;
961 case F_RNY:fname = "native synchronized "; break;
962 default: break;
963 }
964 const char* kptr = strrchr(kname, '/');
965 if (kptr != NULL) kname = kptr + 1;
966 int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s",
967 str, fname, kname, mname, sname);
968 if (len < buflen)
969 str = buf;
970#endif //PRODUCT
971 return str;
972}
973
974
975// These are to get information about intrinsics.
976
977#define ID4(x, y, z, f) ((ID3(x, y, z) << vmIntrinsics::log2_FLAG_LIMIT) | (jlong) (f))
978
979static const jlong intrinsic_info_array[vmIntrinsics::ID_LIMIT+1] = {
980#define VM_INTRINSIC_INFO(ignore_id, klass, name, sig, fcode) \
981 ID4(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig), vmIntrinsics::fcode),
982
983 0, VM_INTRINSICS_DO(VM_INTRINSIC_INFO,
984 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
985 0
986#undef VM_INTRINSIC_INFO
987};
988
989inline jlong intrinsic_info(vmIntrinsics::ID id) {
990 return intrinsic_info_array[vmIntrinsics::ID_from((int)id)];
991}
992
993vmSymbols::SID vmIntrinsics::class_for(vmIntrinsics::ID id) {
994 jlong info = intrinsic_info(id);
995 int shift = 2*vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
996 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1021, "");
997 return vmSymbols::SID( (info >> shift) & mask );
998}
999
1000vmSymbols::SID vmIntrinsics::name_for(vmIntrinsics::ID id) {
1001 jlong info = intrinsic_info(id);
1002 int shift = vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
1003 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1022, "");
1004 return vmSymbols::SID( (info >> shift) & mask );
1005}
1006
1007vmSymbols::SID vmIntrinsics::signature_for(vmIntrinsics::ID id) {
1008 jlong info = intrinsic_info(id);
1009 int shift = log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
1010 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1023, "");
1011 return vmSymbols::SID( (info >> shift) & mask );
1012}
1013
1014vmIntrinsics::Flags vmIntrinsics::flags_for(vmIntrinsics::ID id) {
1015 jlong info = intrinsic_info(id);
1016 int shift = 0, mask = right_n_bits(log2_FLAG_LIMIT);
1017 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 15, "");
1018 return Flags( (info >> shift) & mask );
1019}
1020
1021
1022#ifndef PRODUCT
1023// verify_method performs an extra check on a matched intrinsic method
1024
1025static bool match_method(Method* m, Symbol* n, Symbol* s) {
1026 return (m->name() == n &&
1027 m->signature() == s);
1028}
1029
1030static vmIntrinsics::ID match_method_with_klass(Method* m, Symbol* mk) {
1031#define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \
1032 { Symbol* k = vmSymbols::klassname(); \
1033 if (mk == k) { \
1034 Symbol* n = vmSymbols::namepart(); \
1035 Symbol* s = vmSymbols::sigpart(); \
1036 if (match_method(m, n, s)) \
1037 return vmIntrinsics::id; \
1038 } }
1039 VM_INTRINSICS_DO(VM_INTRINSIC_MATCH,
1040 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
1041 return vmIntrinsics::_none;
1042#undef VM_INTRINSIC_MATCH
1043}
1044
1045void vmIntrinsics::verify_method(ID actual_id, Method* m) {
1046 Symbol* mk = m->method_holder()->name();
1047 ID declared_id = match_method_with_klass(m, mk);
1048
1049 if (declared_id == actual_id) return; // success
1050
1051 if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) {
1052 // Here are a few special cases in StrictMath not declared in vmSymbols.hpp.
1053 switch (actual_id) {
1054 case _min:
1055 case _max:
1056 case _dsqrt:
1057 declared_id = match_method_with_klass(m, vmSymbols::java_lang_Math());
1058 if (declared_id == actual_id) return; // acceptable alias
1059 break;
1060 default:
1061 break;
1062 }
1063 }
1064
1065 const char* declared_name = name_at(declared_id);
1066 const char* actual_name = name_at(actual_id);
1067 methodHandle mh = m;
1068 m = NULL;
1069 ttyLocker ttyl;
1070 if (xtty != NULL) {
1071 xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'",
1072 actual_name, declared_name);
1073 xtty->method(mh);
1074 xtty->end_elem("%s", "");
1075 }
1076 if (PrintMiscellaneous && (WizardMode || Verbose)) {
1077 tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):",
1078 declared_name, declared_id, actual_name, actual_id);
1079 mh()->print_short_name(tty);
1080 tty->cr();
1081 }
1082}
1083#endif //PRODUCT
1084