src/share/vm/classfile/verifier.cpp

changeset 2497
3582bf76420e
parent 2322
828eafbd85cc
child 2508
b92c45f2bc75
     1.1 --- a/src/share/vm/classfile/verifier.cpp	Thu Jan 27 13:42:28 2011 -0800
     1.2 +++ b/src/share/vm/classfile/verifier.cpp	Thu Jan 27 16:11:27 2011 -0800
     1.3 @@ -98,10 +98,10 @@
     1.4  }
     1.5  
     1.6  bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
     1.7 +  HandleMark hm;
     1.8    ResourceMark rm(THREAD);
     1.9 -  HandleMark hm;
    1.10  
    1.11 -  symbolHandle exception_name;
    1.12 +  Symbol* exception_name = NULL;
    1.13    const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
    1.14    char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
    1.15  
    1.16 @@ -141,7 +141,7 @@
    1.17          tty->print("Verification for %s has", klassName);
    1.18          tty->print_cr(" exception pending %s ",
    1.19            instanceKlass::cast(PENDING_EXCEPTION->klass())->external_name());
    1.20 -      } else if (!exception_name.is_null()) {
    1.21 +      } else if (exception_name != NULL) {
    1.22          tty->print_cr("Verification for %s failed", klassName);
    1.23        }
    1.24        tty->print_cr("End class verification for: %s", klassName);
    1.25 @@ -150,7 +150,7 @@
    1.26  
    1.27    if (HAS_PENDING_EXCEPTION) {
    1.28      return false; // use the existing exception
    1.29 -  } else if (exception_name.is_null()) {
    1.30 +  } else if (exception_name == NULL) {
    1.31      return true; // verifcation succeeded
    1.32    } else { // VerifyError or ClassFormatError to be created and thrown
    1.33      ResourceMark rm(THREAD);
    1.34 @@ -172,7 +172,7 @@
    1.35  }
    1.36  
    1.37  bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
    1.38 -  symbolOop name = klass->name();
    1.39 +  Symbol* name = klass->name();
    1.40    klassOop refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
    1.41  
    1.42    return (should_verify_for(klass->class_loader(), should_verify_class) &&
    1.43 @@ -202,7 +202,7 @@
    1.44    );
    1.45  }
    1.46  
    1.47 -symbolHandle Verifier::inference_verify(
    1.48 +Symbol* Verifier::inference_verify(
    1.49      instanceKlassHandle klass, char* message, size_t message_len, TRAPS) {
    1.50    JavaThread* thread = (JavaThread*)THREAD;
    1.51    JNIEnv *env = thread->jni_environment();
    1.52 @@ -245,18 +245,17 @@
    1.53    // These numbers are chosen so that VerifyClassCodes interface doesn't need
    1.54    // to be changed (still return jboolean (unsigned char)), and result is
    1.55    // 1 when verification is passed.
    1.56 -  symbolHandle nh(NULL);
    1.57    if (result == 0) {
    1.58      return vmSymbols::java_lang_VerifyError();
    1.59    } else if (result == 1) {
    1.60 -    return nh; // verified.
    1.61 +    return NULL; // verified.
    1.62    } else if (result == 2) {
    1.63 -    THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, nh);
    1.64 +    THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL);
    1.65    } else if (result == 3) {
    1.66      return vmSymbols::java_lang_ClassFormatError();
    1.67    } else {
    1.68      ShouldNotReachHere();
    1.69 -    return nh;
    1.70 +    return NULL;
    1.71    }
    1.72  }
    1.73  
    1.74 @@ -266,12 +265,19 @@
    1.75  
    1.76  ClassVerifier::ClassVerifier(
    1.77      instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS)
    1.78 -    : _thread(THREAD), _exception_type(symbolHandle()), _message(msg),
    1.79 +    : _thread(THREAD), _exception_type(NULL), _message(msg),
    1.80        _message_buffer_len(msg_len), _klass(klass) {
    1.81    _this_type = VerificationType::reference_type(klass->name());
    1.82 +  // Create list to hold symbols in reference area.
    1.83 +  _symbols = new GrowableArray<Symbol*>(100, 0, NULL);
    1.84  }
    1.85  
    1.86  ClassVerifier::~ClassVerifier() {
    1.87 +  // Decrement the reference count for any symbols created.
    1.88 +  for (int i = 0; i < _symbols->length(); i++) {
    1.89 +    Symbol* s = _symbols->at(i);
    1.90 +    s->decrement_refcount();
    1.91 +  }
    1.92  }
    1.93  
    1.94  VerificationType ClassVerifier::object_type() const {
    1.95 @@ -308,7 +314,6 @@
    1.96  }
    1.97  
    1.98  void ClassVerifier::verify_method(methodHandle m, TRAPS) {
    1.99 -  ResourceMark rm(THREAD);
   1.100    _method = m;   // initialize _method
   1.101    if (_verify_verbose) {
   1.102      tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string());
   1.103 @@ -615,7 +620,7 @@
   1.104                VerificationType::null_type(), CHECK_VERIFY(this));
   1.105            } else {
   1.106              VerificationType component =
   1.107 -              atype.get_component(CHECK_VERIFY(this));
   1.108 +              atype.get_component(this, CHECK_VERIFY(this));
   1.109              current_frame.push_stack(component, CHECK_VERIFY(this));
   1.110            }
   1.111            no_control_flow = false; break;
   1.112 @@ -1386,7 +1391,7 @@
   1.113          VerificationType throwable =
   1.114            VerificationType::reference_type(vmSymbols::java_lang_Throwable());
   1.115          bool is_subclass = throwable.is_assignable_from(
   1.116 -          catch_type, current_class(), CHECK_VERIFY(this));
   1.117 +          catch_type, this, CHECK_VERIFY(this));
   1.118          if (!is_subclass) {
   1.119            // 4286534: should throw VerifyError according to recent spec change
   1.120            verify_error(
   1.121 @@ -1473,8 +1478,6 @@
   1.122        if(bci >= start_pc && bci < end_pc) {
   1.123          u1 flags = current_frame->flags();
   1.124          if (this_uninit) {  flags |= FLAG_THIS_UNINIT; }
   1.125 -
   1.126 -        ResourceMark rm(THREAD);
   1.127          StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
   1.128          if (catch_type_index != 0) {
   1.129            // We know that this index refers to a subclass of Throwable
   1.130 @@ -1575,7 +1578,7 @@
   1.131    va_end(va);
   1.132  }
   1.133  
   1.134 -klassOop ClassVerifier::load_class(symbolHandle name, TRAPS) {
   1.135 +klassOop ClassVerifier::load_class(Symbol* name, TRAPS) {
   1.136    // Get current loader and protection domain first.
   1.137    oop loader = current_class()->class_loader();
   1.138    oop protection_domain = current_class()->protection_domain();
   1.139 @@ -1587,8 +1590,8 @@
   1.140  
   1.141  bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
   1.142                                          klassOop target_class,
   1.143 -                                        symbolOop field_name,
   1.144 -                                        symbolOop field_sig,
   1.145 +                                        Symbol* field_name,
   1.146 +                                        Symbol* field_sig,
   1.147                                          bool is_method) {
   1.148    No_Safepoint_Verifier nosafepoint;
   1.149  
   1.150 @@ -1736,7 +1739,7 @@
   1.151  }
   1.152  
   1.153  bool ClassVerifier::name_in_supers(
   1.154 -    symbolOop ref_name, instanceKlassHandle current) {
   1.155 +    Symbol* ref_name, instanceKlassHandle current) {
   1.156    klassOop super = current->super();
   1.157    while (super != NULL) {
   1.158      if (super->klass_part()->name() == ref_name) {
   1.159 @@ -1755,8 +1758,8 @@
   1.160    verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this));
   1.161  
   1.162    // Get field name and signature
   1.163 -  symbolHandle field_name = symbolHandle(THREAD, cp->name_ref_at(index));
   1.164 -  symbolHandle field_sig = symbolHandle(THREAD, cp->signature_ref_at(index));
   1.165 +  Symbol* field_name = cp->name_ref_at(index);
   1.166 +  Symbol* field_sig = cp->signature_ref_at(index);
   1.167  
   1.168    if (!SignatureVerifier::is_valid_type_signature(field_sig)) {
   1.169      class_format_error(
   1.170 @@ -1823,11 +1826,11 @@
   1.171        fieldDescriptor fd;
   1.172        if (stack_object_type == VerificationType::uninitialized_this_type() &&
   1.173            target_class_type.equals(current_type()) &&
   1.174 -          _klass->find_local_field(field_name(), field_sig(), &fd)) {
   1.175 +          _klass->find_local_field(field_name, field_sig, &fd)) {
   1.176          stack_object_type = current_type();
   1.177        }
   1.178        is_assignable = target_class_type.is_assignable_from(
   1.179 -        stack_object_type, current_class(), CHECK_VERIFY(this));
   1.180 +        stack_object_type, this, CHECK_VERIFY(this));
   1.181        if (!is_assignable) {
   1.182          verify_error(bci, "Bad type on operand stack in putfield");
   1.183          return;
   1.184 @@ -1836,9 +1839,9 @@
   1.185      check_protected: {
   1.186        if (_this_type == stack_object_type)
   1.187          break; // stack_object_type must be assignable to _current_class_type
   1.188 -      symbolHandle ref_class_name = symbolHandle(THREAD,
   1.189 -        cp->klass_name_at(cp->klass_ref_index_at(index)));
   1.190 -      if (!name_in_supers(ref_class_name(), current_class()))
   1.191 +      Symbol* ref_class_name =
   1.192 +        cp->klass_name_at(cp->klass_ref_index_at(index));
   1.193 +      if (!name_in_supers(ref_class_name, current_class()))
   1.194          // stack_object_type must be assignable to _current_class_type since:
   1.195          // 1. stack_object_type must be assignable to ref_class.
   1.196          // 2. ref_class must be _current_class or a subclass of it. It can't
   1.197 @@ -1846,12 +1849,12 @@
   1.198          break;
   1.199  
   1.200        klassOop ref_class_oop = load_class(ref_class_name, CHECK);
   1.201 -      if (is_protected_access(current_class(), ref_class_oop, field_name(),
   1.202 -                              field_sig(), false)) {
   1.203 +      if (is_protected_access(current_class(), ref_class_oop, field_name,
   1.204 +                              field_sig, false)) {
   1.205          // It's protected access, check if stack object is assignable to
   1.206          // current class.
   1.207          is_assignable = current_type().is_assignable_from(
   1.208 -          stack_object_type, current_class(), CHECK_VERIFY(this));
   1.209 +          stack_object_type, this, CHECK_VERIFY(this));
   1.210          if (!is_assignable) {
   1.211            verify_error(bci, "Bad access to protected data in getfield");
   1.212            return;
   1.213 @@ -1911,7 +1914,7 @@
   1.214        instanceKlassHandle mh(THREAD, m->method_holder());
   1.215        if (m->is_protected() && !mh->is_same_class_package(_klass())) {
   1.216          bool assignable = current_type().is_assignable_from(
   1.217 -          objectref_type, current_class(), CHECK_VERIFY(this));
   1.218 +          objectref_type, this, CHECK_VERIFY(this));
   1.219          if (!assignable) {
   1.220            verify_error(bci, "Bad access to protected <init> method");
   1.221            return;
   1.222 @@ -1941,8 +1944,8 @@
   1.223    verify_cp_type(index, cp, types, CHECK_VERIFY(this));
   1.224  
   1.225    // Get method name and signature
   1.226 -  symbolHandle method_name(THREAD, cp->name_ref_at(index));
   1.227 -  symbolHandle method_sig(THREAD, cp->signature_ref_at(index));
   1.228 +  Symbol* method_name = cp->name_ref_at(index);
   1.229 +  Symbol* method_sig = cp->signature_ref_at(index);
   1.230  
   1.231    if (!SignatureVerifier::is_valid_method_signature(method_sig)) {
   1.232      class_format_error(
   1.233 @@ -2035,7 +2038,7 @@
   1.234    if (method_name->byte_at(0) == '<') {
   1.235      // Make sure <init> can only be invoked by invokespecial
   1.236      if (opcode != Bytecodes::_invokespecial ||
   1.237 -        method_name() != vmSymbols::object_initializer_name()) {
   1.238 +        method_name != vmSymbols::object_initializer_name()) {
   1.239        verify_error(bci, "Illegal call to internal method");
   1.240        return;
   1.241      }
   1.242 @@ -2044,7 +2047,7 @@
   1.243               && !ref_class_type.equals(VerificationType::reference_type(
   1.244                    current_class()->super()->klass_part()->name()))) {
   1.245      bool subtype = ref_class_type.is_assignable_from(
   1.246 -      current_type(), current_class(), CHECK_VERIFY(this));
   1.247 +      current_type(), this, CHECK_VERIFY(this));
   1.248      if (!subtype) {
   1.249        verify_error(bci, "Bad invokespecial instruction: "
   1.250            "current class isn't assignable to reference class.");
   1.251 @@ -2058,7 +2061,7 @@
   1.252    // Check objectref on operand stack
   1.253    if (opcode != Bytecodes::_invokestatic &&
   1.254        opcode != Bytecodes::_invokedynamic) {
   1.255 -    if (method_name() == vmSymbols::object_initializer_name()) {  // <init> method
   1.256 +    if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
   1.257        verify_invoke_init(bcs, ref_class_type, current_frame,
   1.258          code_length, this_uninit, cp, CHECK_VERIFY(this));
   1.259      } else {   // other methods
   1.260 @@ -2070,22 +2073,22 @@
   1.261            current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
   1.262          if (current_type() != stack_object_type) {
   1.263            assert(cp->cache() == NULL, "not rewritten yet");
   1.264 -          symbolHandle ref_class_name = symbolHandle(THREAD,
   1.265 -            cp->klass_name_at(cp->klass_ref_index_at(index)));
   1.266 +          Symbol* ref_class_name =
   1.267 +            cp->klass_name_at(cp->klass_ref_index_at(index));
   1.268            // See the comments in verify_field_instructions() for
   1.269            // the rationale behind this.
   1.270 -          if (name_in_supers(ref_class_name(), current_class())) {
   1.271 +          if (name_in_supers(ref_class_name, current_class())) {
   1.272              klassOop ref_class = load_class(ref_class_name, CHECK);
   1.273              if (is_protected_access(
   1.274 -                  _klass, ref_class, method_name(), method_sig(), true)) {
   1.275 +                  _klass, ref_class, method_name, method_sig, true)) {
   1.276                // It's protected access, check if stack object is
   1.277                // assignable to current class.
   1.278                bool is_assignable = current_type().is_assignable_from(
   1.279 -                stack_object_type, current_class(), CHECK_VERIFY(this));
   1.280 +                stack_object_type, this, CHECK_VERIFY(this));
   1.281                if (!is_assignable) {
   1.282                  if (ref_class_type.name() == vmSymbols::java_lang_Object()
   1.283                      && stack_object_type.is_array()
   1.284 -                    && method_name() == vmSymbols::clone_name()) {
   1.285 +                    && method_name == vmSymbols::clone_name()) {
   1.286                    // Special case: arrays pretend to implement public Object
   1.287                    // clone().
   1.288                  } else {
   1.289 @@ -2105,7 +2108,7 @@
   1.290    }
   1.291    // Push the result type.
   1.292    if (sig_stream.type() != T_VOID) {
   1.293 -    if (method_name() == vmSymbols::object_initializer_name()) {
   1.294 +    if (method_name == vmSymbols::object_initializer_name()) {
   1.295        // <init> method must have a void return type
   1.296        verify_error(bci, "Return type must be void in <init> method");
   1.297        return;
   1.298 @@ -2130,7 +2133,7 @@
   1.299    }
   1.300  
   1.301    // from_bt[index] contains the array signature which has a length of 2
   1.302 -  symbolHandle sig = oopFactory::new_symbol_handle(
   1.303 +  Symbol* sig = create_temporary_symbol(
   1.304      from_bt[index], 2, CHECK_(VerificationType::bogus_type()));
   1.305    return VerificationType::reference_type(sig);
   1.306  }
   1.307 @@ -2143,7 +2146,6 @@
   1.308  
   1.309    VerificationType component_type =
   1.310      cp_index_to_type(index, cp, CHECK_VERIFY(this));
   1.311 -  ResourceMark rm(THREAD);
   1.312    int length;
   1.313    char* arr_sig_str;
   1.314    if (component_type.is_array()) {     // it's an array
   1.315 @@ -2163,7 +2165,7 @@
   1.316      strncpy(&arr_sig_str[2], component_name, length - 2);
   1.317      arr_sig_str[length - 1] = ';';
   1.318    }
   1.319 -  symbolHandle arr_sig = oopFactory::new_symbol_handle(
   1.320 +  Symbol* arr_sig = create_temporary_symbol(
   1.321      arr_sig_str, length, CHECK_VERIFY(this));
   1.322    VerificationType new_array_type = VerificationType::reference_type(arr_sig);
   1.323    current_frame->push_stack(new_array_type, CHECK_VERIFY(this));
   1.324 @@ -2256,9 +2258,25 @@
   1.325      verify_error(bci, "Method expects a return value");
   1.326      return;
   1.327    }
   1.328 -  bool match = return_type.is_assignable_from(type, _klass, CHECK_VERIFY(this));
   1.329 +  bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this));
   1.330    if (!match) {
   1.331      verify_error(bci, "Bad return type");
   1.332      return;
   1.333    }
   1.334  }
   1.335 +
   1.336 +// The verifier creates symbols which are substrings of Symbols.
   1.337 +// These are stored in the verifier until the end of verification so that
   1.338 +// they can be reference counted.
   1.339 +Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin,
   1.340 +                                               int end, TRAPS) {
   1.341 +  Symbol* sym = SymbolTable::new_symbol(s, begin, end, CHECK_NULL);
   1.342 +  _symbols->push(sym);
   1.343 +  return sym;
   1.344 +}
   1.345 +
   1.346 +Symbol* ClassVerifier::create_temporary_symbol(const char *s, int length, TRAPS) {
   1.347 +  Symbol* sym = SymbolTable::new_symbol(s, length, CHECK_NULL);
   1.348 +  _symbols->push(sym);
   1.349 +  return sym;
   1.350 +}

mercurial