예제 #1
0
void MethodHandles::verify_klass(MacroAssembler* _masm,
                                 Register obj, SystemDictionary::WKID klass_id,
                                 const char* error_message) {
  InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
  KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
  Register temp = rscratch2;
  Register temp2 = rscratch1; // used by MacroAssembler::cmpptr
  Label L_ok, L_bad;
  BLOCK_COMMENT("verify_klass {");
  __ verify_oop(obj);
  __ cbz(obj, L_bad);
  __ push(RegSet::of(temp, temp2), sp);
  __ load_klass(temp, obj);
  __ cmpptr(temp, ExternalAddress((address) klass_addr));
  __ br(Assembler::EQ, L_ok);
  intptr_t super_check_offset = klass->super_check_offset();
  __ ldr(temp, Address(temp, super_check_offset));
  __ cmpptr(temp, ExternalAddress((address) klass_addr));
  __ br(Assembler::EQ, L_ok);
  __ pop(RegSet::of(temp, temp2), sp);
  __ bind(L_bad);
  __ stop(error_message);
  __ BIND(L_ok);
  __ pop(RegSet::of(temp, temp2), sp);
  BLOCK_COMMENT("} verify_klass");
}
예제 #2
0
void MethodHandles::verify_klass(MacroAssembler* _masm,
                                 Register obj, SystemDictionary::WKID klass_id,
                                 const char* error_message) {
  Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
  KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
  Register temp = rdi;
  Register temp2 = noreg;
  LP64_ONLY(temp2 = rscratch1);  // used by MacroAssembler::cmpptr
  Label L_ok, L_bad;
  BLOCK_COMMENT("verify_klass {");
  __ verify_oop(obj);
  __ testptr(obj, obj);
  __ jcc(Assembler::zero, L_bad);
  __ push(temp); if (temp2 != noreg)  __ push(temp2);
#define UNPUSH { if (temp2 != noreg)  __ pop(temp2);  __ pop(temp); }
  __ load_klass(temp, obj);
  __ cmpptr(temp, ExternalAddress((address) klass_addr));
  __ jcc(Assembler::equal, L_ok);
  intptr_t super_check_offset = klass->super_check_offset();
  __ movptr(temp, Address(temp, super_check_offset));
  __ cmpptr(temp, ExternalAddress((address) klass_addr));
  __ jcc(Assembler::equal, L_ok);
  UNPUSH;
  __ bind(L_bad);
  __ STOP(error_message);
  __ BIND(L_ok);
  UNPUSH;
  BLOCK_COMMENT("} verify_klass");
}
예제 #3
0
int instanceMirrorKlass::instance_size(KlassHandle k) {
  if (k() != NULL && k->oop_is_instance()) {
    return align_object_size(size_helper() + instanceKlass::cast(k())->static_field_size());
  }

  return size_helper();
}
예제 #4
0
void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
                                                           HeapWord* obj_ptr) {
  oop obj = (oop)obj_ptr;

  assert(obj != NULL, "NULL object pointer");
  if (UseBiasedLocking && (klass() != NULL)) {
    obj->set_mark(klass->prototype_header());
  } else {
    // May be bootstrapping
    obj->set_mark(markOopDesc::prototype());
  }
}
int klassVtable::initialize_from_super(KlassHandle super) {
  if (super.is_null()) {
    return 0;
  } else {
    // copy methods from superKlass
    // can't inherit from array class, so must be instanceKlass
    assert(super->oop_is_instance(), "must be instance klass");
    instanceKlass* sk = (instanceKlass*)super()->klass_part();
    klassVtable* superVtable = sk->vtable();
    assert(superVtable->length() <= _length, "vtable too short");
#ifdef ASSERT
    superVtable->verify(tty, true);
#endif
    superVtable->copy_vtable_to(table());
#ifndef PRODUCT
    if (PrintVtables && Verbose) {  
      tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length);
    }
#endif
    return superVtable->length();
  }
}
예제 #6
0
void MethodHandles::verify_klass(MacroAssembler* _masm,
                                 Register obj_reg, SystemDictionary::WKID klass_id,
                                 Register temp_reg, Register temp2_reg,
                                 const char* error_message) {
  Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
  KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
  Label L_ok, L_bad;
  BLOCK_COMMENT("verify_klass {");
  __ verify_oop(obj_reg);
  __ cmpdi(CCR0, obj_reg, 0);
  __ beq(CCR0, L_bad);
  __ load_klass(temp_reg, obj_reg);
  __ load_const_optimized(temp2_reg, (address) klass_addr);
  __ ld(temp2_reg, 0, temp2_reg);
  __ cmpd(CCR0, temp_reg, temp2_reg);
  __ beq(CCR0, L_ok);
  __ ld(temp_reg, klass->super_check_offset(), temp_reg);
  __ cmpd(CCR0, temp_reg, temp2_reg);
  __ beq(CCR0, L_ok);
  __ BIND(L_bad);
  __ stop(error_message);
  __ BIND(L_ok);
  BLOCK_COMMENT("} verify_klass");
}
예제 #7
0
void CHA::process_class(KlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, symbolHandle name, symbolHandle signature) {    
  // recursively add non-abstract subclasses of r to receivers list
  assert(!r->is_interface(), "should call process_interface instead");
  for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) {
    // preorder traversal, so check subclasses first
    if (s->is_interface()) {
      // can only happen if r == Object
      assert(r->superklass() == NULL, "must be klass Object");
    } else {
      process_class(s, receivers, methods, name, signature);
    }
  }
  // now check r itself (after subclasses because of preorder)
  if (!methods->is_full()) {
    // don't add abstract classes to receivers list
    // (but still consider their methods -- they may be non-abstract)
    if (!receivers->is_full() && !r->is_abstract()) receivers->push(r);
    methodOop m = NULL;
    if (r->oop_is_instance()) m = instanceKlass::cast(r())->find_method(name(), signature()); 
    if (m != NULL && !m->is_abstract()) {
      if (!methods->contains(m)) methods->push(m);
    }
  }
}
예제 #8
0
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
  CallInfo callinfo;
  LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
  methodHandle method = callinfo.selected_method();
  assert(method.not_null(), "should have thrown exception");
  //signature->
  // Invoke the method
  printf("%s[%d] [tid: %lu]: 开始调用Java中的静态方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), klass->external_name(), name->as_C_string(), signature->as_C_string());
  JavaCalls::call(result, method, args, CHECK);
}
예제 #9
0
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
  CallInfo callinfo;
  Handle receiver = args->receiver();
  KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass());

  LinkResolver::resolve_virtual_call(
          callinfo, receiver, recvrKlass, spec_klass, name, signature,
          KlassHandle(), false, true, CHECK);
  methodHandle method = callinfo.selected_method();
  assert(method.not_null(), "should have thrown exception");

  printf("%s[%d] [tid: %lu]: 开始调用Java中的方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), spec_klass->external_name(), name->as_C_string(), signature->as_C_string());

  // Invoke the method
  JavaCalls::call(result, method, args, CHECK);
}
예제 #10
0
 bool is_anonymous() {
   assert(AnonymousClasses || _host_klass.is_null(), "");
   return _host_klass.not_null();
 }
예제 #11
0
 bool is_anonymous() {
   assert(EnableInvokeDynamic || _host_klass.is_null(), "");
   return _host_klass.not_null();
 }
klassOop
instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int itable_len,
                                            int static_field_size,
                                            unsigned nonstatic_oop_map_count,
                                            AccessFlags access_flags,
                                            ReferenceType rt,
                                            KlassHandle host_klass, TRAPS) {

  const int nonstatic_oop_map_size =
    instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count);
  int size = align_object_offset(vtable_len) + align_object_offset(itable_len);
  if (access_flags.is_interface() || !host_klass.is_null()) {
    size += align_object_offset(nonstatic_oop_map_size);
  } else {
    size += nonstatic_oop_map_size;
  }
  if (access_flags.is_interface()) {
    size += (int)sizeof(klassOop)/HeapWordSize;
  }
  if (!host_klass.is_null()) {
    size += (int)sizeof(klassOop)/HeapWordSize;
  }
  size = instanceKlass::object_size(size);

  // Allocation
  KlassHandle h_this_klass(THREAD, as_klassOop());
  KlassHandle k;
  if (rt == REF_NONE) {
    if (name != vmSymbols::java_lang_Class()) {
      // regular klass
      instanceKlass o;
      k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL);
    } else {
      // Class
      instanceMirrorKlass o;
      k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL);
    }
  } else {
    // reference klass
    instanceRefKlass o;
    k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL);
  }
  {
    No_Safepoint_Verifier no_safepoint; // until k becomes parsable
    instanceKlass* ik = (instanceKlass*) k()->klass_part();
    assert(!k()->is_parsable(), "not expecting parsability yet.");

    // The sizes of these these three variables are used for determining the
    // size of the instanceKlassOop. It is critical that these are set to the right
    // sizes before the first GC, i.e., when we allocate the mirror.
    ik->set_vtable_length(vtable_len);
    ik->set_itable_length(itable_len);
    ik->set_static_field_size(static_field_size);
    ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size);
    ik->set_access_flags(access_flags);
    ik->set_is_anonymous(!host_klass.is_null());
    assert(k()->size() == size, "wrong size for object");

    ik->set_array_klasses(NULL);
    ik->set_methods(NULL);
    ik->set_method_ordering(NULL);
    ik->set_local_interfaces(NULL);
    ik->set_transitive_interfaces(NULL);
    ik->init_implementor();
    ik->set_fields(NULL, 0);
    ik->set_constants(NULL);
    ik->set_class_loader(NULL);
    ik->set_protection_domain(NULL);
    ik->set_signers(NULL);
    ik->set_source_file_name(NULL);
    ik->set_source_debug_extension(NULL, 0);
    ik->set_array_name(NULL);
    ik->set_inner_classes(NULL);
    ik->set_static_oop_field_count(0);
    ik->set_nonstatic_field_size(0);
    ik->set_is_marked_dependent(false);
    ik->set_init_state(instanceKlass::allocated);
    ik->set_init_thread(NULL);
    ik->set_reference_type(rt);
    ik->set_oop_map_cache(NULL);
    ik->set_jni_ids(NULL);
    ik->set_osr_nmethods_head(NULL);
    ik->set_breakpoints(NULL);
    ik->init_previous_versions();
    ik->set_generic_signature(NULL);
    ik->release_set_methods_jmethod_ids(NULL);
    ik->release_set_methods_cached_itable_indices(NULL);
    ik->set_class_annotations(NULL);
    ik->set_fields_annotations(NULL);
    ik->set_methods_annotations(NULL);
    ik->set_methods_parameter_annotations(NULL);
    ik->set_methods_default_annotations(NULL);
    ik->set_jvmti_cached_class_field_map(NULL);
    ik->set_initial_method_idnum(0);
    assert(k()->is_parsable(), "should be parsable here.");

    // initialize the non-header words to zero
    intptr_t* p = (intptr_t*)k();
    for (int index = instanceKlass::header_size(); index < size; index++) {
      p[index] = NULL_WORD;
    }

    // To get verify to work - must be set to partial loaded before first GC point.
    k()->set_partially_loaded();
  }

  Atomic::inc(&instanceKlass::_total_instanceKlass_count);
  return k();
}
예제 #13
0
void ciField::initialize_from(fieldDescriptor* fd) {
  // Get the flags, offset, and canonical holder of the field.
  _flags = ciFlags(fd->access_flags());
  _offset = fd->offset();
  _holder = CURRENT_ENV->get_object(fd->field_holder())->as_instance_klass();

  // Check to see if the field is constant.
  if (_holder->is_initialized() && this->is_final()) {
    if (!this->is_static()) {
      // A field can be constant if it's a final static field or if
      // it's a final non-static field of a trusted class (classes in
      // java.lang.invoke and sun.invoke packages and subpackages).
      if (trust_final_non_static_fields(_holder)) {
        _is_constant = true;
        return;
      }
      _is_constant = false;
      return;
    }

    // This field just may be constant.  The only cases where it will
    // not be constant are:
    //
    // 1. The field holds a non-perm-space oop.  The field is, strictly
    //    speaking, constant but we cannot embed non-perm-space oops into
    //    generated code.  For the time being we need to consider the
    //    field to be not constant.
    // 2. The field is a *special* static&final field whose value
    //    may change.  The three examples are java.lang.System.in,
    //    java.lang.System.out, and java.lang.System.err.

    KlassHandle k = _holder->get_klassOop();
    assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
    if( k() == SystemDictionary::System_klass() ) {
      // Check offsets for case 2: System.in, System.out, or System.err
      if( _offset == java_lang_System::in_offset_in_bytes()  ||
          _offset == java_lang_System::out_offset_in_bytes() ||
          _offset == java_lang_System::err_offset_in_bytes() ) {
        _is_constant = false;
        return;
      }
    }

    Handle mirror = k->java_mirror();

    _is_constant = true;
    switch(type()->basic_type()) {
    case T_BYTE:
      _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset));
      break;
    case T_CHAR:
      _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset));
      break;
    case T_SHORT:
      _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset));
      break;
    case T_BOOLEAN:
      _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset));
      break;
    case T_INT:
      _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset));
      break;
    case T_FLOAT:
      _constant_value = ciConstant(mirror->float_field(_offset));
      break;
    case T_DOUBLE:
      _constant_value = ciConstant(mirror->double_field(_offset));
      break;
    case T_LONG:
      _constant_value = ciConstant(mirror->long_field(_offset));
      break;
    case T_OBJECT:
    case T_ARRAY:
      {
        oop o = mirror->obj_field(_offset);

        // A field will be "constant" if it is known always to be
        // a non-null reference to an instance of a particular class,
        // or to a particular array.  This can happen even if the instance
        // or array is not perm.  In such a case, an "unloaded" ciArray
        // or ciInstance is created.  The compiler may be able to use
        // information about the object's class (which is exact) or length.

        if (o == NULL) {
          _constant_value = ciConstant(type()->basic_type(), ciNullObject::make());
        } else {
          _constant_value = ciConstant(type()->basic_type(), CURRENT_ENV->get_object(o));
          assert(_constant_value.as_object() == CURRENT_ENV->get_object(o), "check interning");
        }
      }
    }
  } else {
    _is_constant = false;
  }
}