示例#1
0
bool symbolKlass::allocate_symbols(int names_count, const char** names,
                                   int* lengths, symbolOop* sym_oops, TRAPS) {
  if (UseConcMarkSweepGC || UseParallelGC) {
    // Concurrent GC needs to mark all the allocated symbol oops after
    // the remark phase which isn't done below (except the first symbol oop).
    // So return false which will let the symbols be allocated one by one.
    // The parallel collector uses an object start array to find the
    // start of objects on a dirty card.  The object start array is not
    // updated for the start of each symbol so is not precise.  During
    // object array verification this causes a verification failure.
    // In a product build this causes extra searching for the start of
    // a symbol.  As with the concurrent collector a return of false will
    // cause each symbol to be allocated separately and in the case
    // of the parallel collector will cause the object
    // start array to be updated.
    return false;
  }

  assert(names_count > 0, "can't allocate 0 symbols");

  int total_size = 0;
  int i, sizes[SymbolTable::symbol_alloc_batch_size];
  for (i=0; i<names_count; i++) {
    int len = lengths[i];
    if (len > symbolOopDesc::max_length()) {
      return false;
    }
    int sz = symbolOopDesc::object_size(len);
    sizes[i] = sz * HeapWordSize;
    total_size += sz;
  }
  symbolKlassHandle h_k(THREAD, as_klassOop());
  HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size);
  if (base == NULL) {
    return false;
  }

  // CAN'T take any safepoint during the initialization of the symbol oops !
  No_Safepoint_Verifier nosafepoint;

  klassOop sk = h_k();
  int pos = 0;
  for (i=0; i<names_count; i++) {
    symbolOop s = (symbolOop) (((char*)base) + pos);
    s->set_mark(markOopDesc::prototype());
    s->set_klass(sk);
    s->set_utf8_length(lengths[i]);
    const char* name = names[i];
    for (int j=0; j<lengths[i]; j++) {
      s->byte_at_put(j, name[j]);
    }

    assert(s->is_parsable(), "should be parsable here.");

    sym_oops[i] = s;
    pos += sizes[i];
  }
  return true;
}
示例#2
0
constMethodOop constMethodKlass::allocate(int byte_code_size,
                                          int compressed_line_number_size,
                                          int localvariable_table_length,
                                          int checked_exceptions_length,
                                          bool is_conc_safe,
                                          TRAPS) {

  int size = constMethodOopDesc::object_size(byte_code_size,
                                             compressed_line_number_size,
                                             localvariable_table_length,
                                             checked_exceptions_length);
  KlassHandle h_k(THREAD, as_klassOop());
  constMethodOop cm = (constMethodOop)
    CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
  assert(!cm->is_parsable(), "Not yet safely parsable");
  No_Safepoint_Verifier no_safepoint;
  cm->set_interpreter_kind(Interpreter::invalid);
  cm->init_fingerprint();
  cm->set_method(NULL);
  cm->set_stackmap_data(NULL);
  cm->set_exception_table(NULL);
  cm->set_code_size(byte_code_size);
  cm->set_constMethod_size(size);
  cm->set_inlined_tables_length(checked_exceptions_length,
                                compressed_line_number_size,
                                localvariable_table_length);
  assert(cm->size() == size, "wrong size for object");
  cm->set_is_conc_safe(is_conc_safe);
  cm->set_partially_loaded();
  assert(cm->is_parsable(), "Is safely parsable by gc");
  return cm;
}
/**
 * 为某一类型对应的java.lang.Class实例分配存储空间
 */
instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
  // Query before forming handle.
  int size = instance_size(k);
  KlassHandle h_k(THREAD, as_klassOop());
  instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL);
  return i;
}
typeArrayOop TypeArrayKlass::allocate(int length, HeapColor color, TRAPS) {
    assert(log2_element_size() >= 0, "bad scale");
    if (length >= 0) {
        if (length <= max_length()) {
            size_t size = typeArrayOopDesc::object_size(layout_helper(), length);
            KlassHandle h_k(THREAD, this);
            typeArrayOop t;
            CollectedHeap* ch = Universe::heap();
            /*
            if (size < ch->large_typearray_limit()) {
            */
            t = (typeArrayOop)CollectedHeap::array_allocate(h_k, (int)size, length,
                    color, CHECK_NULL);
            /*
            } else {
              t = (typeArrayOop)CollectedHeap::large_typearray_allocate(h_k, (int)size,
                                               length, color, CHECK_NULL);
            }
            */
            //assert(t->is_parsable(), "Don't publish unless parsable");
            return t;
        } else {
            report_java_out_of_memory("Requested array size exceeds VM limit");
            THROW_OOP_0(Universe::out_of_memory_error_array_size());
        }
    } else {
        THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
    }
}
// ------------------------------------------------------------------
// ciObjectFactory::create_new_object
//
// Create a new ciObject from a Metadata*.
//
// Implementation note: this functionality could be virtual behavior
// of the oop itself.  For now, we explicitly marshal the object.
ciMetadata* ciObjectFactory::create_new_object(Metadata* o) {
  EXCEPTION_CONTEXT;

  if (o->is_klass()) {
    KlassHandle h_k(THREAD, (Klass*)o);
    Klass* k = (Klass*)o;
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (Method*)o);
    return new (arena()) ciMethod(h_m);
  } else if (o->is_methodData()) {
    // Hold methodHandle alive - might not be necessary ???
    methodHandle h_m(THREAD, ((MethodData*)o)->method());
    return new (arena()) ciMethodData((MethodData*)o);
  }

  // The oop is of some type not supported by the compiler interface.
  ShouldNotReachHere();
  return NULL;
}
typeArrayOop typeArrayKlass::allocate_permanent(int length, TRAPS) {
  if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
  int size = typeArrayOopDesc::object_size(layout_helper(), length);
  KlassHandle h_k(THREAD, as_klassOop());
  typeArrayOop t = (typeArrayOop)
    CollectedHeap::permanent_array_allocate(h_k, size, length, CHECK_NULL);
  assert(t->is_parsable(), "Can't publish until parsable");
  return t;
}
compiledICHolderOop compiledICHolderKlass::allocate(TRAPS) {
  KlassHandle h_k(THREAD, as_klassOop());
  int size = compiledICHolderOopDesc::object_size();
  compiledICHolderOop c = (compiledICHolderOop)
    CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
  c->set_holder_method(NULL);
  c->set_holder_klass(NULL);
  return c;
}
instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
  // Query before forming handle.
  int size = instance_size(k);
  KlassHandle h_k(THREAD, this);
  instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);

  // Since mirrors can be variable sized because of the static fields, store
  // the size in the mirror itself.
  java_lang_Class::set_oop_size(i, size);

  return i;
}
methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) {
  int size = methodDataOopDesc::compute_allocation_size_in_words(method());
  KlassHandle h_k(THREAD, as_klassOop());
  methodDataOop mdo =
    (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_0);
  assert(!mdo->is_parsable(), "not expecting parsability yet.");
  No_GC_Verifier nogc;          // the init function should not GC
  mdo->initialize(method());

  assert(mdo->is_parsable(), "should be parsable here.");
  assert(size == mdo->object_size(), "wrong size for methodDataOop");
  return mdo;
}
// ------------------------------------------------------------------
// ciObjectFactory::create_new_metadata
//
// Create a new ciMetadata from a Metadata*.
//
// Implementation note: in order to keep Metadata live, an auxiliary ciObject
// is used, which points to it's holder.
ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) {
  EXCEPTION_CONTEXT;

  // Hold metadata from unloading by keeping it's holder alive.
  if (_initialized && o->is_klass()) {
    Klass* holder = ((Klass*)o);
    if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
      // Though ciInstanceKlass records class loader oop, it's not enough to keep
      // VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
      // It is enough to record a ciObject, since cached elements are never removed
      // during ciObjectFactory lifetime. ciObjectFactory itself is created for
      // every compilation and lives for the whole duration of the compilation.
      ciObject* h = get(holder->klass_holder());
    }
  }

  if (o->is_klass()) {
    KlassHandle h_k(THREAD, (Klass*)o);
    Klass* k = (Klass*)o;
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (Method*)o);
    ciEnv *env = CURRENT_THREAD_ENV;
    ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder());
    return new (arena()) ciMethod(h_m, holder);
  } else if (o->is_methodData()) {
    // Hold methodHandle alive - might not be necessary ???
    methodHandle h_m(THREAD, ((MethodData*)o)->method());
    return new (arena()) ciMethodData((MethodData*)o);
  }

  // The Metadata* is of some type not supported by the compiler interface.
  ShouldNotReachHere();
  return NULL;
}
示例#11
0
symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) {
  // Don't allow symbol oops to be created which cannot fit in a symbolOop.
  if (len > symbolOopDesc::max_length()) {
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), 
                "name is too long to represent");
  }
  int size = symbolOopDesc::object_size(len);
  symbolKlassHandle h_k(THREAD, as_klassOop());
  symbolOop sym = (symbolOop)
    CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_0);
  assert(!sym->is_parsable(), "not expecting parsability yet.");
  sym->set_next(NULL);
  sym->set_utf8_length(len);
  for (int i = 0; i < len; i++) {
    sym->byte_at_put(i, name[i]);
  }
  // Let the first emptySymbol be created and
  // ensure only one is ever created.
  assert(sym->is_parsable() || Universe::emptySymbol() == NULL,
         "should be parsable here.");
  return sym;
}
示例#12
0
typeArrayOop TypeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) {
    assert(log2_element_size() >= 0, "bad scale");
    if (length >= 0) {
        if (length <= max_length()) {
            size_t size = typeArrayOopDesc::object_size(layout_helper(), length);
            KlassHandle h_k(THREAD, this);
            typeArrayOop t;
            CollectedHeap* ch = Universe::heap();
            if (do_zero) {
                t = (typeArrayOop)CollectedHeap::array_allocate(h_k, (int)size, length, CHECK_NULL);
            } else {
                t = (typeArrayOop)CollectedHeap::array_allocate_nozero(h_k, (int)size, length, CHECK_NULL);
            }
            return t;
        } else {
            report_java_out_of_memory("Requested array size exceeds VM limit");
            JvmtiExport::post_array_size_exhausted();
            THROW_OOP_0(Universe::out_of_memory_error_array_size());
        }
    } else {
        THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
    }
}
示例#13
0
methodOop methodKlass::allocate(constMethodHandle xconst,
                                AccessFlags access_flags, TRAPS) {
  int size = methodOopDesc::object_size(access_flags.is_native());
  KlassHandle h_k(THREAD, as_klassOop());
  assert(xconst()->is_parsable(), "possible publication protocol violation");
  methodOop m = (methodOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
  assert(!m->is_parsable(), "not expecting parsability yet.");

  No_Safepoint_Verifier no_safepoint;  // until m becomes parsable below
  m->set_constMethod(xconst());
  m->set_access_flags(access_flags);
  m->set_method_size(size);
  m->set_name_index(0);
  m->set_signature_index(0);
#ifdef CC_INTERP
  m->set_result_index(T_VOID);
#endif
  m->set_constants(NULL);
  m->set_max_stack(0);
  m->set_max_locals(0);
  m->set_intrinsic_id(vmIntrinsics::_none);
  m->set_method_data(NULL);
  m->set_interpreter_throwout_count(0);
  m->set_vtable_index(methodOopDesc::garbage_vtable_index);

  // Fix and bury in methodOop
  m->set_interpreter_entry(NULL); // sets i2i entry and from_int
  m->set_highest_tier_compile(CompLevel_none);
  m->set_adapter_entry(NULL);
  m->clear_code(); // from_c/from_i get set to c2i/i2i

  if (access_flags.is_native()) {
    m->clear_native_function();
    m->set_signature_handler(NULL);
  }

  NOT_PRODUCT(m->set_compiled_invocation_count(0);)
示例#14
0
// ------------------------------------------------------------------
// ciObjectFactory::create_new_object
//
// Create a new ciObject from an oop.
//
// Implementation note: this functionality could be virtual behavior
// of the oop itself.  For now, we explicitly marshal the object.
ciObject* ciObjectFactory::create_new_object(oop o) {
  EXCEPTION_CONTEXT;

  if (o->is_symbol()) {
    symbolHandle h_o(THREAD, (symbolOop)o);
    assert(vmSymbols::find_sid(h_o()) == vmSymbols::NO_SID, "");
    return new (arena()) ciSymbol(h_o, vmSymbols::NO_SID);
  } else if (o->is_klass()) {
    KlassHandle h_k(THREAD, (klassOop)o);
    Klass* k = ((klassOop)o)->klass_part();
    if (k->oop_is_instance()) {
      return new (arena()) ciInstanceKlass(h_k);
    } else if (k->oop_is_objArray()) {
      return new (arena()) ciObjArrayKlass(h_k);
    } else if (k->oop_is_typeArray()) {
      return new (arena()) ciTypeArrayKlass(h_k);
    } else if (k->oop_is_method()) {
      return new (arena()) ciMethodKlass(h_k);
    } else if (k->oop_is_symbol()) {
      return new (arena()) ciSymbolKlass(h_k);
    } else if (k->oop_is_klass()) {
      if (k->oop_is_objArrayKlass()) {
        return new (arena()) ciObjArrayKlassKlass(h_k);
      } else if (k->oop_is_typeArrayKlass()) {
        return new (arena()) ciTypeArrayKlassKlass(h_k);
      } else if (k->oop_is_instanceKlass()) {
        return new (arena()) ciInstanceKlassKlass(h_k);
      } else {
        assert(o == Universe::klassKlassObj(), "bad klassKlass");
        return new (arena()) ciKlassKlass(h_k);
      }
    }
  } else if (o->is_method()) {
    methodHandle h_m(THREAD, (methodOop)o);
    return new (arena()) ciMethod(h_m);
  } else if (o->is_methodData()) {
    methodDataHandle h_md(THREAD, (methodDataOop)o);
    return new (arena()) ciMethodData(h_md);
  } else if (o->is_instance()) {
    instanceHandle h_i(THREAD, (instanceOop)o);
    if (java_dyn_CallSite::is_instance(o))
      return new (arena()) ciCallSite(h_i);
    else if (java_dyn_MethodHandle::is_instance(o))
      return new (arena()) ciMethodHandle(h_i);
    else
      return new (arena()) ciInstance(h_i);
  } else if (o->is_objArray()) {
    objArrayHandle h_oa(THREAD, (objArrayOop)o);
    return new (arena()) ciObjArray(h_oa);
  } else if (o->is_typeArray()) {
    typeArrayHandle h_ta(THREAD, (typeArrayOop)o);
    return new (arena()) ciTypeArray(h_ta);
  } else if (o->is_constantPoolCache()) {
    constantPoolCacheHandle h_cpc(THREAD, (constantPoolCacheOop) o);
    return new (arena()) ciCPCache(h_cpc);
  }

  // The oop is of some type not supported by the compiler interface.
  ShouldNotReachHere();
  return NULL;
}