hotspot/src/share/vm/prims/nativeLookup.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 2534 08dac9ce0cd7
child 4571 80b553bddc26
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 1
diff changeset
     2
 * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_nativeLookup.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
static void mangle_name_on(outputStream* st, symbolOop name, int begin, int end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
  char* bytes = (char*)name->bytes() + begin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
  char* end_bytes = (char*)name->bytes() + end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
  while (bytes < end_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
    jchar c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
    bytes = UTF8::next(bytes, &c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
    if (c <= 0x7f && isalnum(c)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
      st->put((char) c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
           if (c == '_') st->print("_1");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
      else if (c == '/') st->print("_");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
      else if (c == ';') st->print("_2");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
      else if (c == '[') st->print("_3");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
      else               st->print("_%.5x", c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
static void mangle_name_on(outputStream* st, symbolOop name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  mangle_name_on(st, name, 0, name->utf8_length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
char* NativeLookup::pure_jni_name(methodHandle method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  stringStream st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  // Prefix
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  st.print("Java_");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  // Klass name
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  mangle_name_on(&st, method->klass_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  st.print("_");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  // Method name
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  mangle_name_on(&st, method->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  return st.as_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
char* NativeLookup::long_jni_name(methodHandle method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  // Signature ignore the wrapping parenteses and the trailing return type
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  stringStream st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  symbolOop signature = method->signature();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  st.print("__");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  // find ')'
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  int end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  for (end = 0; end < signature->utf8_length() && signature->byte_at(end) != ')'; end++);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  // skip first '('
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  mangle_name_on(&st, signature, 1, end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  return st.as_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 1
diff changeset
    81
  void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
static address lookup_special_native(char* jni_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  // NB: To ignore the jni prefix and jni postfix strstr is used matching.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  if (!JDK_Version::is_gte_jdk14x_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    // These functions only exist for compatibility with 1.3.1 and earlier
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    // Intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    if (strstr(jni_name, "Java_java_io_ObjectOutputStream_getPrimitiveFieldValues") != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
      return CAST_FROM_FN_PTR(address, JVM_GetPrimitiveFieldValues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    // Intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    if (strstr(jni_name, "Java_java_io_ObjectInputStream_setPrimitiveFieldValues") != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
      return CAST_FROM_FN_PTR(address, JVM_SetPrimitiveFieldValues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  if (strstr(jni_name, "Java_sun_misc_Unsafe_registerNatives") != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    return CAST_FROM_FN_PTR(address, JVM_RegisterUnsafeMethods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  }
2534
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 1
diff changeset
   101
  if (strstr(jni_name, "Java_sun_dyn_MethodHandleNatives_registerNatives") != NULL) {
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 1
diff changeset
   102
    return CAST_FROM_FN_PTR(address, JVM_RegisterMethodHandleMethods);
08dac9ce0cd7 6655638: dynamic languages need method handles
jrose
parents: 1
diff changeset
   103
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  if (strstr(jni_name, "Java_sun_misc_Perf_registerNatives") != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    return CAST_FROM_FN_PTR(address, JVM_RegisterPerfMethods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
address NativeLookup::lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  address entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  // Compute complete JNI name for style
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  stringStream st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  if (os_style) os::print_jni_name_prefix_on(&st, args_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  st.print_raw(pure_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  st.print_raw(long_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  if (os_style) os::print_jni_name_suffix_on(&st, args_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  char* jni_name = st.as_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  // If the loader is null we have a system class, so we attempt a lookup in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  // the native Java library. This takes care of any bootstrapping problems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  // gets found the first time around - otherwise an infinite loop can occure. This is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  // another VM/library dependency
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  Handle loader(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
                instanceKlass::cast(method->method_holder())->class_loader());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  if (loader.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    entry = lookup_special_native(jni_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    if (entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
       entry = (address) hpi::dll_lookup(os::native_java_library(), jni_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
    if (entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
      in_base_library = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
      return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  // Otherwise call static method findNative in ClassLoader
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  KlassHandle   klass (THREAD, SystemDictionary::classloader_klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  JavaValue result(T_LONG);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  JavaCalls::call_static(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
                         klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
                         vmSymbolHandles::findNative_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
                         vmSymbolHandles::classloader_string_long_signature(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
                         // Arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
                         loader,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
                         name_arg,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
                         CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  entry = (address) (intptr_t) result.get_jlong();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  if (entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    // findNative didn't find it, if there are any agent libraries look in them
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    AgentLibrary* agent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      entry = (address) hpi::dll_lookup(agent->os_lib(), jni_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      if (entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
        return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
// Check all the formats of native implementation name to see if there is one
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
// for the specified method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  address entry = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  in_base_library = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  // Compute pure name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  char* pure_name = pure_jni_name(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  // Compute argument size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  int args_size = 1                             // JNIEnv
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
                + (method->is_static() ? 1 : 0) // class for static methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
                + method->size_of_parameters(); // actual parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // 1) Try JNI short style
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  entry = lookup_style(method, pure_name, "",        args_size, true,  in_base_library, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  if (entry != NULL) return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // Compute long name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  char* long_name = long_jni_name(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  // 2) Try JNI long style
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  entry = lookup_style(method, pure_name, long_name, args_size, true,  in_base_library, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  if (entry != NULL) return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  // 3) Try JNI short style without os prefix/suffix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  entry = lookup_style(method, pure_name, "",        args_size, false, in_base_library, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  if (entry != NULL) return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  // 4) Try JNI long style without os prefix/suffix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  return entry; // NULL indicates not found
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
// Check if there are any JVM TI prefixes which have been applied to the native method name.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
// If any are found, remove them before attemping the look up of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
// native implementation again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
// See SetNativeMethodPrefix in the JVM TI Spec for more details.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
address NativeLookup::lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  int prefix_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  char* in_name = method->name()->as_C_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  char* wrapper_name = in_name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  // last applied prefix will be first -- go backwards
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  for (int i = prefix_count-1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    char* prefix = prefixes[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    size_t prefix_len = strlen(prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    if (strncmp(prefix, wrapper_name, prefix_len) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      // has this prefix remove it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
      wrapper_name += prefix_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  if (wrapper_name != in_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    // we have a name for a wrapping method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    int wrapper_name_len = (int)strlen(wrapper_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    symbolHandle wrapper_symbol(THREAD, SymbolTable::probe(wrapper_name, wrapper_name_len));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    if (!wrapper_symbol.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
      KlassHandle kh(method->method_holder());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
      methodOop wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
                                                                  method->signature());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
      if (wrapper_method != NULL && !wrapper_method->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
        // we found a wrapper method, use its native entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
        method->set_is_prefixed_native();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
        return lookup_entry(wrapper_method, in_base_library, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  address entry = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  entry = lookup_entry(method, in_base_library, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  if (entry != NULL) return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  // standard native method resolution has failed.  Check if there are any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  // JVM TI prefixes which have been applied to the native method name.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  entry = lookup_entry_prefixed(method, in_base_library, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  if (entry != NULL) return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  // Native function not found, throw UnsatisfiedLinkError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  THROW_MSG_0(vmSymbols::java_lang_UnsatisfiedLinkError(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
              method->name_and_sig_as_C_string());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  if (!method->has_native_function()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    address entry = lookup_base(method, in_base_library, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    method->set_native_function(entry,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
      methodOopDesc::native_bind_event_is_interesting);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    // -verbose:jni printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    if (PrintJNIResolving) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
      ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
      tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        Klass::cast(method->method_holder())->external_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
        method->name()->as_C_string());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  return method->native_function();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
address NativeLookup::base_library_lookup(const char* class_name, const char* method_name, const char* signature) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  bool in_base_library = true;  // SharedRuntime inits some math methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  symbolHandle c_name = oopFactory::new_symbol_handle(class_name,  CATCH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  symbolHandle m_name = oopFactory::new_symbol_handle(method_name, CATCH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  symbolHandle s_name = oopFactory::new_symbol_handle(signature,   CATCH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  // Find the class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  klassOop k = SystemDictionary::resolve_or_fail(c_name, true, CATCH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  instanceKlassHandle klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // Find method and invoke standard lookup
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  methodHandle method (THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
                       klass->uncached_lookup_method(m_name(), s_name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  address result = lookup(method, in_base_library, CATCH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  assert(in_base_library, "must be in basic library");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  guarantee(result != NULL, "must be non NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
}