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