hotspot/src/share/vm/runtime/reflection.cpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 15102 0a86564e5f61
child 17860 1ad3f2d9b4eb
permissions -rw-r--r--
8006005: Fix constant pool index validation and alignment trap for method parameter reflection Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data. Reviewed-by: jrose, dholmes Contributed-by: eric.mccorkle@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
     2
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4581
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4581
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4581
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "classfile/javaClasses.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "classfile/symbolTable.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "classfile/verifier.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "classfile/vmSymbols.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "interpreter/linkResolver.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "memory/oopFactory.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "memory/resourceArea.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "memory/universe.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
#include "oops/instanceKlass.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "oops/objArrayKlass.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
#include "oops/objArrayOop.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    38
#include "prims/jvm.h"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    39
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    40
#include "runtime/handles.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    41
#include "runtime/javaCalls.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    42
#include "runtime/reflection.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    43
#include "runtime/reflectionUtils.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    44
#include "runtime/signature.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    45
#include "runtime/vframe.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
#define JAVA_1_5_VERSION                  49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
    49
static void trace_class_resolution(Klass* to_class) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  int line_number = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  const char * source_file = NULL;
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
    53
  Klass* caller = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  JavaThread* jthread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  if (jthread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    vframeStream vfst(jthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    // skip over any frames belonging to java.lang.Class
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    while (!vfst.at_end() &&
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
    59
           vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
      vfst.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    if (!vfst.at_end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
      // this frame is a likely suspect
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
      caller = vfst.method()->method_holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      line_number = vfst.method()->line_number_from_bci(vfst.bci());
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
    66
      Symbol* s = vfst.method()->method_holder()->source_file_name();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      if (s != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
        source_file = s->as_C_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  if (caller != NULL) {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
    73
    const char * from = caller->external_name();
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
    74
    const char * to = to_class->external_name();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    // print in a single call to reduce interleaving between threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    if (source_file != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
      tty->print("RESOLVE %s %s %s:%d (reflection)\n", from, to, source_file, line_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
      tty->print("RESOLVE %s %s (reflection)\n", from, to);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
oop Reflection::box(jvalue* value, BasicType type, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  if (type == T_VOID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  if (type == T_OBJECT || type == T_ARRAY) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    // regular objects are not boxed
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    return (oop) value->l;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  if (result == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  if (box == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  return java_lang_boxing_object::get_value(box, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  // Note:  box is really the unboxed oop.  It might even be a Short, etc.!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  value->l = (jobject) box;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  return T_OBJECT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
void Reflection::widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  assert(wide_type != current_type, "widen should not be called with identical types");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  switch (wide_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
    case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
      switch (current_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
        case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
          value->s = (jshort) value->b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
      switch (current_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
        case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
          value->i = (jint) value->b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
        case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
          value->i = (jint) value->c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
        case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
          value->i = (jint) value->s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
      switch (current_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
        case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
          value->j = (jlong) value->b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
        case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
          value->j = (jlong) value->c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
        case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
          value->j = (jlong) value->s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
        case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
          value->j = (jlong) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      switch (current_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
        case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
          value->f = (jfloat) value->b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
        case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
          value->f = (jfloat) value->c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
        case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
          value->f = (jfloat) value->s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
        case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
          value->f = (jfloat) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
        case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
          value->f = (jfloat) value->j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
      switch (current_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
        case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
          value->d = (jdouble) value->b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
        case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
          value->d = (jdouble) value->c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
        case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
          value->d = (jdouble) value->s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
        case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
          value->d = (jdouble) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
        case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
          value->d = (jdouble) value->f;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
        case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
          value->d = (jdouble) value->j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
      break;  // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
BasicType Reflection::array_get(jvalue* value, arrayOop a, int index, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  if (!a->is_within_bounds(index)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    THROW_(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), T_ILLEGAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  if (a->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    value->l = (jobject) objArrayOop(a)->obj_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    return T_OBJECT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    assert(a->is_typeArray(), "just checking");
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   215
    BasicType type = TypeArrayKlass::cast(a->klass())->element_type();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    switch (type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
      case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
        value->z = typeArrayOop(a)->bool_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        value->c = typeArrayOop(a)->char_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
      case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
        value->f = typeArrayOop(a)->float_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
      case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
        value->d = typeArrayOop(a)->double_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
      case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
        value->b = typeArrayOop(a)->byte_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
      case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
        value->s = typeArrayOop(a)->short_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
      case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
        value->i = typeArrayOop(a)->int_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
      case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        value->j = typeArrayOop(a)->long_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
        return T_ILLEGAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    return type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  if (!a->is_within_bounds(index)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  if (a->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    if (value_type == T_OBJECT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
      oop obj = (oop) value->l;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
      if (obj != NULL) {
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   257
        Klass* element_klass = ObjArrayKlass::cast(a->klass())->element_klass();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
        if (!obj->is_a(element_klass)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
          THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
      objArrayOop(a)->obj_at_put(index, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    assert(a->is_typeArray(), "just checking");
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   266
    BasicType array_type = TypeArrayKlass::cast(a->klass())->element_type();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    if (array_type != value_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
      // The widen operation can potentially throw an exception, but cannot block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
      // so typeArrayOop a is safe if the call succeeds.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      widen(value, value_type, array_type, CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    switch (array_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
      case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
        typeArrayOop(a)->bool_at_put(index, value->z);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
      case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        typeArrayOop(a)->char_at_put(index, value->c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      case T_FLOAT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
        typeArrayOop(a)->float_at_put(index, value->f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
      case T_DOUBLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
        typeArrayOop(a)->double_at_put(index, value->d);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
      case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
        typeArrayOop(a)->byte_at_put(index, value->b);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
      case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
        typeArrayOop(a)->short_at_put(index, value->s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
      case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
        typeArrayOop(a)->int_at_put(index, value->i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
      case T_LONG:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
        typeArrayOop(a)->long_at_put(index, value->j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        THROW(vmSymbols::java_lang_IllegalArgumentException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   304
Klass* Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  BasicType type = java_lang_Class::primitive_type(basic_type_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  if (type == T_VOID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
    return Universe::typeArrayKlassObj(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   315
oop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) {
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   316
  BasicType type = TypeArrayKlass::cast(basic_type_arrayklass)->element_type();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  return Universe::java_mirror(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  if (element_mirror == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    THROW_0(vmSymbols::java_lang_NullPointerException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  if (length < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  if (java_lang_Class::is_primitive(element_mirror)) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   329
    Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   330
    return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  } else {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   332
    Klass* k = java_lang_Class::as_Klass(element_mirror);
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   333
    if (k->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    return oopFactory::new_objArray(k, length, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  assert(dim_array->is_typeArray(), "just checking");
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   343
  assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  if (element_mirror == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
    THROW_0(vmSymbols::java_lang_NullPointerException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  int len = dim_array->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  if (len <= 0 || len > MAX_DIM) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  jint dimensions[MAX_DIM];   // C array copy of intArrayOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  for (int i = 0; i < len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    int d = dim_array->int_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    if (d < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
      THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    dimensions[i] = d;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   363
  Klass* klass;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  int dim = len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  if (java_lang_Class::is_primitive(element_mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  } else {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   368
    klass = java_lang_Class::as_Klass(element_mirror);
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   369
    if (klass->oop_is_array()) {
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   370
      int k_dim = ArrayKlass::cast(klass)->dimension();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
      if (k_dim + len > MAX_DIM) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
        THROW_0(vmSymbols::java_lang_IllegalArgumentException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
      dim += k_dim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  }
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   377
  klass = klass->array_klass(dim, CHECK_NULL);
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   378
  oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  assert(obj->is_array(), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  return arrayOop(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
oop Reflection::array_component_type(oop mirror, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  if (java_lang_Class::is_primitive(mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   389
  Klass* klass = java_lang_Class::as_Klass(mirror);
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   390
  if (!klass->oop_is_array()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   394
  oop result = ArrayKlass::cast(klass)->component_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  oop result2 = NULL;
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   397
  if (ArrayKlass::cast(klass)->dimension() == 1) {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   398
    if (klass->oop_is_typeArray()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
      result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    } else {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   401
      result2 = ObjArrayKlass::cast(klass)->element_klass()->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  } else {
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13728
diff changeset
   404
    Klass* lower_dim = ArrayKlass::cast(klass)->lower_dimension();
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   405
    assert(lower_dim->oop_is_array(), "just checking");
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   406
    result2 = lower_dim->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  assert(result == result2, "results must be consistent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
#endif //ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   414
bool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  // field_class  : declaring class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  // acc          : declared field access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // target_class : for protected
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  // Check if field or method is accessible to client.  Throw an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  // IllegalAccessException and return false if not.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  // The "client" is the class associated with the nearest real frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  // getCallerClass already skips Method.invoke frames, so pass 0 in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  // that case (same as classic).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  assert(THREAD->is_Java_thread(), "sanity check");
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   427
  Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  if (client_class != field_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
    if (!verify_class_access(client_class, field_class, false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
        || !verify_field_access(client_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
                                field_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
                                field_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
                                acc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
                                false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
      THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  // Additional test for protected members: JLS 6.6.2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  if (acc.is_protected()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
    if (target_class != client_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      if (!is_same_class_package(client_class, field_class)) {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   445
        if (!target_class->is_subclass_of(client_class)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
          THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  // Passed all tests
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   457
bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  // Verify that current_class can access new_class.  If the classloader_only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  // flag is set, we automatically allow any accesses in which current_class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  // doesn't have a classloader.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  if ((current_class == NULL) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
      (current_class == new_class) ||
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   463
      (InstanceKlass::cast(new_class)->is_public()) ||
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
      is_same_class_package(current_class, new_class)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  // New (1.4) reflection implementation. Allow all accesses from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  // sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  if (   JDK_Version::is_gte_jdk14x_version()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
      && UseNewReflection
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   471
      && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
14385
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   475
  // Also allow all accesses from
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   476
  // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   477
  if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) {
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   478
    return true;
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   479
  }
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   480
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  return can_relax_access_check_for(current_class, new_class, classloader_only);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   484
static bool under_host_klass(InstanceKlass* ik, Klass* host_klass) {
1550
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   485
  DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   486
  for (;;) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   487
    Klass* hc = (Klass*) ik->host_klass();
1550
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   488
    if (hc == NULL)        return false;
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   489
    if (hc == host_klass)  return true;
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   490
    ik = InstanceKlass::cast(hc);
1550
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   491
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   492
    // There's no way to make a host class loop short of patching memory.
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   493
    // Therefore there cannot be a loop here unles there's another bug.
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   494
    // Still, let's check for it.
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   495
    assert(--inf_loop_check > 0, "no host_klass loop");
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   496
  }
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   497
}
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   498
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
bool Reflection::can_relax_access_check_for(
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   500
    Klass* accessor, Klass* accessee, bool classloader_only) {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   501
  InstanceKlass* accessor_ik = InstanceKlass::cast(accessor);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   502
  InstanceKlass* accessee_ik  = InstanceKlass::cast(accessee);
1550
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   503
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   504
  // If either is on the other's host_klass chain, access is OK,
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   505
  // because one is inside the other.
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   506
  if (under_host_klass(accessor_ik, accessee) ||
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   507
      under_host_klass(accessee_ik, accessor))
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   508
    return true;
be2fc37a817f 6653858: dynamic languages need to be able to load anonymous classes
jrose
parents: 670
diff changeset
   509
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  if (RelaxAccessControlCheck ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
      (accessor_ik->major_version() < JAVA_1_5_VERSION &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
       accessee_ik->major_version() < JAVA_1_5_VERSION)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
    return classloader_only &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
      Verifier::relax_verify_for(accessor_ik->class_loader()) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
      accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
      accessor_ik->class_loader() == accessee_ik->class_loader();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   522
bool Reflection::verify_field_access(Klass* current_class,
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   523
                                     Klass* resolved_class,
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   524
                                     Klass* field_class,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
                                     AccessFlags access,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
                                     bool classloader_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
                                     bool protected_restriction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  // Verify that current_class can access a field of field_class, where that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  // field's access bits are "access".  We assume that we've already verified
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  // that current_class can access field_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  // If the classloader_only flag is set, we automatically allow any accesses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  // in which current_class doesn't have a classloader.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  // "resolved_class" is the runtime type of "field_class". Sometimes we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  // need this distinction (e.g. if all we have is the runtime type, or during
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  // class file parsing when we only care about the static type); in that case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  // callers should ensure that resolved_class == field_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  if ((current_class == NULL) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      (current_class == field_class) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
      access.is_public()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  if (access.is_protected()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    if (!protected_restriction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
      // See if current_class is a subclass of field_class
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   549
      if (current_class->is_subclass_of(field_class)) {
362
00cf4bffd828 6622385: Accessing protected static methods
kamg
parents: 224
diff changeset
   550
        if (access.is_static() || // static fields are ok, see 6622385
00cf4bffd828 6622385: Accessing protected static methods
kamg
parents: 224
diff changeset
   551
            current_class == resolved_class ||
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
            field_class == resolved_class ||
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   553
            current_class->is_subclass_of(resolved_class) ||
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   554
            resolved_class->is_subclass_of(current_class)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
          return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  if (!access.is_private() && is_same_class_package(current_class, field_class)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  // New (1.4) reflection implementation. Allow all accesses from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  // sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  if (   JDK_Version::is_gte_jdk14x_version()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
      && UseNewReflection
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   569
      && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
14385
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   573
  // Also allow all accesses from
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   574
  // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   575
  if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) {
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   576
    return true;
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   577
  }
959bbcc16725 7200776: Implement default methods in interfaces
kamg
parents: 13952
diff changeset
   578
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  return can_relax_access_check_for(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    current_class, field_class, classloader_only);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   584
bool Reflection::is_same_class_package(Klass* class1, Klass* class2) {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   585
  return InstanceKlass::cast(class1)->is_same_class_package(class2);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   588
bool Reflection::is_same_package_member(Klass* class1, Klass* class2, TRAPS) {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   589
  return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD);
2332
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   590
}
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   591
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
// Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
// throw an incompatible class change exception
2332
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   595
// If inner_is_member, require the inner to be a member of the outer.
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   596
// If !inner_is_member, require the inner to be anonymous (a non-member).
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   597
// Caller is responsible for figuring out in advance which case must be true.
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   598
void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   599
                                       bool inner_is_member, TRAPS) {
12231
6a9cfc59a18a 7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents: 10504
diff changeset
   600
  InnerClassesIterator iter(outer);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  constantPoolHandle cp   (THREAD, outer->constants());
12231
6a9cfc59a18a 7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents: 10504
diff changeset
   602
  for (; !iter.done(); iter.next()) {
6a9cfc59a18a 7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents: 10504
diff changeset
   603
     int ioff = iter.inner_class_info_index();
6a9cfc59a18a 7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents: 10504
diff changeset
   604
     int ooff = iter.outer_class_info_index();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
2332
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   606
     if (inner_is_member && ioff != 0 && ooff != 0) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   607
        Klass* o = cp->klass_at(ooff, CHECK);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
        if (o == outer()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   609
          Klass* i = cp->klass_at(ioff, CHECK);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
          if (i == inner()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
     }
2332
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   615
     if (!inner_is_member && ioff != 0 && ooff == 0 &&
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   616
         cp->klass_name_at_matches(inner, ioff)) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   617
        Klass* i = cp->klass_at(ioff, CHECK);
2332
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   618
        if (i == inner()) {
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   619
          return;
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   620
        }
5c7b6f4ce0a1 6814659: separable cleanups and subroutines for 6655638
jrose
parents: 1550
diff changeset
   621
     }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  // 'inner' not declared as an inner klass in outer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  Exceptions::fthrow(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
    THREAD_AND_LOCATION,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   628
    vmSymbols::java_lang_IncompatibleClassChangeError(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    "%s and %s disagree on InnerClasses attribute",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
    outer->external_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    inner->external_name()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
// Utility method converting a single SignatureStream element into java.lang.Class instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  switch (ss->type()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
      assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
      return java_lang_Class::primitive_mirror(ss->type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    case T_OBJECT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
    case T_ARRAY:
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   644
      Symbol* name        = ss->as_symbol(CHECK_NULL);
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
   645
      oop loader            = method->method_holder()->class_loader();
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
   646
      oop protection_domain = method->method_holder()->protection_domain();
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   647
      Klass* k = SystemDictionary::resolve_or_fail(
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   648
                                       name,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
                                       Handle(THREAD, loader),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
                                       Handle(THREAD, protection_domain),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
                                       true, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
      if (TraceClassResolution) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
        trace_class_resolution(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
      }
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
   655
      return k->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
  // Allocate array holding parameter types (java.lang.Class instances)
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 2332
diff changeset
   662
  objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
  objArrayHandle mirrors (THREAD, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
  int index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  // Collect parameter types
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   666
  ResourceMark rm(THREAD);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   667
  Symbol*  signature  = method->signature();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  SignatureStream ss(signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  while (!ss.at_return_type()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
    mirrors->obj_at_put(index++, mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
    ss.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  assert(index == parameter_count, "invalid parameter count");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  if (return_type != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
    // Collect return type as well
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
    assert(ss.at_return_type(), "return type should be present");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
    *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  return mirrors;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
objArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  return method->resolved_checked_exceptions(CHECK_(objArrayHandle()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   688
Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  // Basic types
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   690
  BasicType type = vmSymbols::signature_type(signature);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  if (type != T_OBJECT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    return Handle(THREAD, Universe::java_mirror(type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   695
  oop loader = InstanceKlass::cast(k())->class_loader();
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   696
  oop protection_domain = k()->protection_domain();
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   697
  Klass* result = SystemDictionary::resolve_or_fail(signature,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
                                    Handle(THREAD, loader),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
                                    Handle(THREAD, protection_domain),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
                                    true, CHECK_(Handle()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  if (TraceClassResolution) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
    trace_class_resolution(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   706
  oop nt = result->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  return Handle(THREAD, nt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  assert(!method()->is_initializer() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
         (for_constant_pool_access && method()->is_static()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
         (method()->name() == vmSymbols::class_initializer_name()
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
   717
    && method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  instanceKlassHandle holder (THREAD, method->method_holder());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  int slot = method->method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   721
  Symbol*  signature  = method->signature();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  int parameter_count = ArgumentCount(signature).size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  oop return_type_oop = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  Handle return_type(THREAD, return_type_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
  if (exception_types.is_null()) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   733
  Symbol*  method_name = method->name();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  Handle name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  if (intern_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    // intern_name is only true with UseNewReflection
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   737
    oop name_oop = StringTable::intern(method_name, CHECK_NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    name = Handle(THREAD, name_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    name = java_lang_String::create_from_symbol(method_name, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  }
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   742
  if (name == NULL) return NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  Handle mh = java_lang_reflect_Method::create(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  java_lang_reflect_Method::set_slot(mh(), slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  java_lang_reflect_Method::set_name(mh(), name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
  java_lang_reflect_Method::set_return_type(mh(), return_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
  java_lang_reflect_Method::set_parameter_types(mh(), parameter_types());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
  java_lang_reflect_Method::set_exception_types(mh(), exception_types());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  java_lang_reflect_Method::set_modifiers(mh(), modifiers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  java_lang_reflect_Method::set_override(mh(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  if (java_lang_reflect_Method::has_signature_field() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
      method->generic_signature() != NULL) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   758
    Symbol*  gs = method->generic_signature();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
    java_lang_reflect_Method::set_signature(mh(), sig());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  if (java_lang_reflect_Method::has_annotations_field()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   763
    typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   764
    java_lang_reflect_Method::set_annotations(mh(), an_oop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
  if (java_lang_reflect_Method::has_parameter_annotations_field()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   767
    typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   768
    java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
  if (java_lang_reflect_Method::has_annotation_default_field()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   771
    typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   772
    java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
  }
15097
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   774
  if (java_lang_reflect_Method::has_type_annotations_field()) {
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   775
    typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL);
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   776
    java_lang_reflect_Method::set_type_annotations(mh(), an_oop);
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   777
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  return mh();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
oop Reflection::new_constructor(methodHandle method, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  assert(method()->is_initializer(), "should call new_method instead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  instanceKlassHandle  holder (THREAD, method->method_holder());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
  int slot = method->method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   788
  Symbol*  signature  = method->signature();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  int parameter_count = ArgumentCount(signature).size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  if (parameter_types.is_null()) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  if (exception_types.is_null()) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
  int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
  Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  java_lang_reflect_Constructor::set_slot(ch(), slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
  java_lang_reflect_Constructor::set_exception_types(ch(), exception_types());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
  java_lang_reflect_Constructor::set_modifiers(ch(), modifiers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  java_lang_reflect_Constructor::set_override(ch(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
  if (java_lang_reflect_Constructor::has_signature_field() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
      method->generic_signature() != NULL) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   808
    Symbol*  gs = method->generic_signature();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
    java_lang_reflect_Constructor::set_signature(ch(), sig());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  if (java_lang_reflect_Constructor::has_annotations_field()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   813
    typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   814
    java_lang_reflect_Constructor::set_annotations(ch(), an_oop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  if (java_lang_reflect_Constructor::has_parameter_annotations_field()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   817
    typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   818
    java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  return ch();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   825
  Symbol*  field_name = fd->name();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
  Handle name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  if (intern_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    // intern_name is only true with UseNewReflection
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   829
    oop name_oop = StringTable::intern(field_name, CHECK_NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
    name = Handle(THREAD, name_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  }
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   834
  Symbol*  signature  = fd->signature();
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   835
  instanceKlassHandle  holder    (THREAD, fd->field_holder());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  Handle type = new_type(signature, holder, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
   839
  java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
  java_lang_reflect_Field::set_slot(rh(), fd->index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  java_lang_reflect_Field::set_name(rh(), name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  java_lang_reflect_Field::set_type(rh(), type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  java_lang_reflect_Field::set_override(rh(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
  if (java_lang_reflect_Field::has_signature_field() &&
13101
67539edd246d 7177409: Perf regression in JVM_GetClassDeclaredFields after generic signature changes.
jiangli
parents: 12231
diff changeset
   847
      fd->has_generic_signature()) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   848
    Symbol*  gs = fd->generic_signature();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    java_lang_reflect_Field::set_signature(rh(), sig());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  if (java_lang_reflect_Field::has_annotations_field()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   853
    typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   854
    java_lang_reflect_Field::set_annotations(rh(), an_oop);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  }
15097
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   856
  if (java_lang_reflect_Field::has_type_annotations_field()) {
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   857
    typeArrayOop an_oop = Annotations::make_java_array(fd->type_annotations(), CHECK_NULL);
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   858
    java_lang_reflect_Field::set_type_annotations(rh(), an_oop);
9db149412e0e 8004823: Add VM support for type annotation reflection
stefank
parents: 14488
diff changeset
   859
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
  return rh();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
15102
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   863
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   864
                              int flags, TRAPS) {
15194
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   865
  Handle name;
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   866
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   867
  // A null symbol here translates to the empty string
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   868
  if(NULL != sym) {
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   869
    name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   870
  } else {
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   871
    name = java_lang_String::create_from_str("", CHECK_NULL);
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   872
  }
a35093d73168 8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents: 15102
diff changeset
   873
15102
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   874
  Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   875
  java_lang_reflect_Parameter::set_name(rh(), name());
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   876
  java_lang_reflect_Parameter::set_modifiers(rh(), flags);
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   877
  java_lang_reflect_Parameter::set_executable(rh(), method());
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   878
  java_lang_reflect_Parameter::set_index(rh(), index);
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   879
  return rh();
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   880
}
0a86564e5f61 8004728: Add hotspot support for parameter reflection
coleenp
parents: 15097
diff changeset
   881
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
                                                KlassHandle recv_klass, Handle receiver, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
  assert(!method.is_null() , "method should not be null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  CallInfo info;
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   888
  Symbol*  signature  = method->signature();
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   889
  Symbol*  name       = method->name();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
                                       name, signature,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
                                       KlassHandle(), false, true,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
                                       CHECK_(methodHandle()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
  return info.selected_method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
                       Handle receiver, bool override, objArrayHandle ptypes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
                       BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  methodHandle method;      // actual method to invoke
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
  KlassHandle target_klass; // target klass, receiver's klass for non-static
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  // Ensure klass is initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  klass->initialize(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  bool is_static = reflected_method->is_static();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  if (is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
    // ignore receiver argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    method = reflected_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
    target_klass = klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
    // check for null receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
    if (receiver.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
      THROW_0(vmSymbols::java_lang_NullPointerException());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
    // Check class of receiver against class declaring method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    if (!receiver->is_a(klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
    // target klass is receiver's klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
    target_klass = KlassHandle(THREAD, receiver->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
    // no need to resolve if method is private or <init>
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
      method = reflected_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
      // resolve based on the receiver
14391
df0a1573d5bd 8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents: 14385
diff changeset
   930
      if (reflected_method->method_holder()->is_interface()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
        // resolve interface call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
        if (ReflectionWrapResolutionErrors) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
          // new default: 6531596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
          // Match resolution errors with those thrown due to reflection inlining
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
          // Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
          if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
          // Method resolution threw an exception; wrap it in an InvocationTargetException
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
            oop resolution_exception = PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
            CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
            JavaCallArguments args(Handle(THREAD, resolution_exception));
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   942
            THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   943
                vmSymbols::throwable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
                &args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
      }  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
        // if the method can be overridden, we resolve using the vtable index.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
        int index  = reflected_method->vtable_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
        method = reflected_method;
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   953
        if (index != Method::nonvirtual_vtable_index) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
          // target_klass might be an arrayKlassOop but all vtables start at
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
          // the same place. The cast is to avoid virtual call and assertion.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   956
          InstanceKlass* inst = (InstanceKlass*)target_klass();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
          method = methodHandle(THREAD, inst->method_at_vtable(index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
        if (!method.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
          // Check for abstract methods as well
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
          if (method->is_abstract()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
            // new default: 6531596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
            if (ReflectionWrapResolutionErrors) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
              ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
              Handle h_origexception = Exceptions::new_exception(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
                     vmSymbols::java_lang_AbstractMethodError(),
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   967
                     Method::name_and_sig_as_C_string(target_klass(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
                     method->name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
                     method->signature()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
              JavaCallArguments args(h_origexception);
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   971
              THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
   972
                vmSymbols::throwable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
                &args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
              ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
              THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(),
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   977
                        Method::name_and_sig_as_C_string(target_klass(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
                                                                method->name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
                                                                method->signature()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
  // I believe this is a ShouldNotGetHere case which requires
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  // an internal vtable bug. If you ever get this please let Karen know.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
  if (method.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
    ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14391
diff changeset
   992
                Method::name_and_sig_as_C_string(klass(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
                                                        reflected_method->name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
                                                        reflected_method->signature()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  // In the JDK 1.4 reflection implementation, the security check is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  // done at the Java level
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  // Access checking (unless overridden by Method)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  if (!override) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
    if (!(klass->is_public() && reflected_method->is_public())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
      bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
      if (!access) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
        return NULL; // exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  } // !(Universe::is_gte_jdk14x_version() && UseNewReflection)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  assert(ptypes->is_objArray(), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  int args_len = args.is_null() ? 0 : args->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  // Check number of arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  if (ptypes->length() != args_len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  // Create object to contain parameters for the JavaCall
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  JavaCallArguments java_args(method->size_of_parameters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
  if (!is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
    java_args.push_oop(receiver);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
  for (int i = 0; i < args_len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
    oop type_mirror = ptypes->obj_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    oop arg = args->obj_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    if (java_lang_Class::is_primitive(type_mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
      jvalue value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
      BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
      BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
      if (ptype != atype) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
        widen(&value, atype, ptype, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
      switch (ptype) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
        case T_BOOLEAN:     java_args.push_int(value.z);    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
        case T_CHAR:        java_args.push_int(value.c);    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
        case T_BYTE:        java_args.push_int(value.b);    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
        case T_SHORT:       java_args.push_int(value.s);    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
        case T_INT:         java_args.push_int(value.i);    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
        case T_LONG:        java_args.push_long(value.j);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
        case T_FLOAT:       java_args.push_float(value.f);  break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
        case T_DOUBLE:      java_args.push_double(value.d); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
      if (arg != NULL) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1051
        Klass* k = java_lang_Class::as_Klass(type_mirror);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
        if (!arg->is_a(k)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
      Handle arg_handle(THREAD, arg);         // Create handle for argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
      java_args.push_oop(arg_handle); // Push handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
  assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
  // All oops (including receiver) is passed in as Handles. An potential oop is returned as an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
  // oop (i.e., NOT as an handle)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
  JavaValue result(rtype);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
  JavaCalls::call(&result, method, &java_args, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
  if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
    // Method threw an exception; wrap it in an InvocationTargetException
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
    oop target_exception = PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
    CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
    JavaCallArguments args(Handle(THREAD, target_exception));
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
  1073
    THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7397
diff changeset
  1074
                vmSymbols::throwable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
                &args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
      narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
    return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  switch (narrow_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
    case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
     value->z = (jboolean) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
     return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
    case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
     value->b = (jbyte) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
     return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
    case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
     value->c = (jchar) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
     return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
    case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
     value->s = (jshort) value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
     return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
      break; // fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  return java_lang_Class::primitive_type(basic_type_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
// This would be nicer if, say, java.lang.reflect.Method was a subclass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
// of java.lang.reflect.Constructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  oop mirror             = java_lang_reflect_Method::clazz(method_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  int slot               = java_lang_reflect_Method::slot(method_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
  bool override          = java_lang_reflect_Method::override(method_mirror) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
  oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
  BasicType rtype;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
  if (java_lang_Class::is_primitive(return_type_mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
    rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
    rtype = T_OBJECT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1127
  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1128
  Method* m = klass->method_with_idnum(slot);
224
6a257cd604e7 6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents: 1
diff changeset
  1129
  if (m == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  }
224
6a257cd604e7 6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents: 1
diff changeset
  1132
  methodHandle method(THREAD, m);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
  return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  oop mirror             = java_lang_reflect_Constructor::clazz(constructor_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  int slot               = java_lang_reflect_Constructor::slot(constructor_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  bool override          = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1144
  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1145
  Method* m = klass->method_with_idnum(slot);
224
6a257cd604e7 6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents: 1
diff changeset
  1146
  if (m == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
  }
224
6a257cd604e7 6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents: 1
diff changeset
  1149
  methodHandle method(THREAD, m);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
  assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  // Make sure klass gets initialize
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  klass->initialize(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  // Create new instance (the receiver)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  klass->check_valid_for_instantiation(false, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
  Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
  // Ignore result from call and return receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
  invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  return receiver();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
}