提交 e73d3ff8 编写于 作者: N nloodin

Merge

......@@ -1349,6 +1349,7 @@ static void merge_in_new_methods(InstanceKlass* klass,
// Replace klass methods with new merged lists
klass->set_methods(merged_methods);
klass->set_initial_method_idnum(new_size);
ClassLoaderData* cld = klass->class_loader_data();
MetadataFactory::free_array(cld, original_methods);
......
......@@ -36,8 +36,10 @@
class Verifier : AllStatic {
public:
enum {
STRICTER_ACCESS_CTRL_CHECK_VERSION = 49,
STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50,
INVOKEDYNAMIC_MAJOR_VERSION = 51
INVOKEDYNAMIC_MAJOR_VERSION = 51,
NO_RELAX_ACCESS_CTRL_CHECK_VERSION = 52
};
typedef enum { ThrowException, NoException } Mode;
......
......@@ -60,10 +60,11 @@ void* _ValueObj::operator new [](size_t size) { ShouldNotCallThis(); return 0;
void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); }
void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
size_t word_size, bool read_only, TRAPS) {
size_t word_size, bool read_only,
MetaspaceObj::Type type, TRAPS) {
// Klass has it's own operator new
return Metaspace::allocate(loader_data, word_size, read_only,
Metaspace::NonClassType, CHECK_NULL);
type, CHECK_NULL);
}
bool MetaspaceObj::is_shared() const {
......
......@@ -268,8 +268,55 @@ class MetaspaceObj {
bool is_shared() const;
void print_address_on(outputStream* st) const; // nonvirtual address printing
#define METASPACE_OBJ_TYPES_DO(f) \
f(Unknown) \
f(Class) \
f(Symbol) \
f(TypeArrayU1) \
f(TypeArrayU2) \
f(TypeArrayU4) \
f(TypeArrayU8) \
f(TypeArrayOther) \
f(Method) \
f(ConstMethod) \
f(MethodData) \
f(ConstantPool) \
f(ConstantPoolCache) \
f(Annotation) \
f(MethodCounters)
#define METASPACE_OBJ_TYPE_DECLARE(name) name ## Type,
#define METASPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
enum Type {
// Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
METASPACE_OBJ_TYPES_DO(METASPACE_OBJ_TYPE_DECLARE)
_number_of_types
};
static const char * type_name(Type type) {
switch(type) {
METASPACE_OBJ_TYPES_DO(METASPACE_OBJ_TYPE_NAME_CASE)
default:
ShouldNotReachHere();
return NULL;
}
}
static MetaspaceObj::Type array_type(size_t elem_size) {
switch (elem_size) {
case 1: return TypeArrayU1Type;
case 2: return TypeArrayU2Type;
case 4: return TypeArrayU4Type;
case 8: return TypeArrayU8Type;
default:
return TypeArrayOtherType;
}
}
void* operator new(size_t size, ClassLoaderData* loader_data,
size_t word_size, bool read_only, Thread* thread);
size_t word_size, bool read_only,
Type type, Thread* thread);
// can't use TRAPS from this header file.
void operator delete(void* p) { ShouldNotCallThis(); }
};
......
......@@ -713,6 +713,23 @@ class SpaceManager : public CHeapObj<mtClass> {
#ifdef ASSERT
void verify_allocated_blocks_words();
#endif
size_t get_raw_word_size(size_t word_size) {
// If only the dictionary is going to be used (i.e., no
// indexed free list), then there is a minimum size requirement.
// MinChunkSize is a placeholder for the real minimum size JJJ
size_t byte_size = word_size * BytesPerWord;
size_t byte_size_with_overhead = byte_size + Metablock::overhead();
size_t raw_bytes_size = MAX2(byte_size_with_overhead,
Metablock::min_block_byte_size());
raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
size_t raw_word_size = raw_bytes_size / BytesPerWord;
assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
return raw_word_size;
}
};
uint const SpaceManager::_small_chunk_limit = 4;
......@@ -2320,19 +2337,7 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size,
MetaWord* SpaceManager::allocate(size_t word_size) {
MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
// If only the dictionary is going to be used (i.e., no
// indexed free list), then there is a minimum size requirement.
// MinChunkSize is a placeholder for the real minimum size JJJ
size_t byte_size = word_size * BytesPerWord;
size_t byte_size_with_overhead = byte_size + Metablock::overhead();
size_t raw_bytes_size = MAX2(byte_size_with_overhead,
Metablock::min_block_byte_size());
raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
size_t raw_word_size = raw_bytes_size / BytesPerWord;
assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
size_t raw_word_size = get_raw_word_size(word_size);
BlockFreelist* fl = block_freelists();
MetaWord* p = NULL;
// Allocation from the dictionary is expensive in the sense that
......@@ -2896,6 +2901,9 @@ void Metaspace::initialize(Mutex* lock,
if (class_chunk != NULL) {
class_vsm()->add_chunk(class_chunk, true);
}
_alloc_record_head = NULL;
_alloc_record_tail = NULL;
}
size_t Metaspace::align_word_size_up(size_t word_size) {
......@@ -3000,12 +3008,14 @@ void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
}
Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
bool read_only, MetadataType mdtype, TRAPS) {
bool read_only, MetaspaceObj::Type type, TRAPS) {
if (HAS_PENDING_EXCEPTION) {
assert(false, "Should not allocate with exception pending");
return NULL; // caller does a CHECK_NULL too
}
MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
// SSS: Should we align the allocations and make sure the sizes are aligned.
MetaWord* result = NULL;
......@@ -3015,13 +3025,13 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
// with the SymbolTable_lock. Dumping is single threaded for now. We'll have
// to revisit this for application class data sharing.
if (DumpSharedSpaces) {
if (read_only) {
result = loader_data->ro_metaspace()->allocate(word_size, NonClassType);
} else {
result = loader_data->rw_metaspace()->allocate(word_size, NonClassType);
}
assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity");
Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace();
result = space->allocate(word_size, NonClassType);
if (result == NULL) {
report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
} else {
space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
}
return Metablock::initialize(result, word_size);
}
......@@ -3056,6 +3066,38 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
return Metablock::initialize(result, word_size);
}
void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
assert(DumpSharedSpaces, "sanity");
AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize);
if (_alloc_record_head == NULL) {
_alloc_record_head = _alloc_record_tail = rec;
} else {
_alloc_record_tail->_next = rec;
_alloc_record_tail = rec;
}
}
void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
address last_addr = (address)bottom();
for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
address ptr = rec->_ptr;
if (last_addr < ptr) {
closure->doit(last_addr, MetaspaceObj::UnknownType, ptr - last_addr);
}
closure->doit(ptr, rec->_type, rec->_byte_size);
last_addr = ptr + rec->_byte_size;
}
address top = ((address)bottom()) + used_bytes_slow(Metaspace::NonClassType);
if (last_addr < top) {
closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr);
}
}
void Metaspace::purge() {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
......
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -127,6 +127,23 @@ class Metaspace : public CHeapObj<mtClass> {
static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; }
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now.
void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
class AllocRecord : public CHeapObj<mtClass> {
public:
AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
: _next(NULL), _ptr(ptr), _type(type), _byte_size(byte_size) {}
AllocRecord *_next;
address _ptr;
MetaspaceObj::Type _type;
int _byte_size;
};
AllocRecord * _alloc_record_head;
AllocRecord * _alloc_record_tail;
public:
Metaspace(Mutex* lock, MetaspaceType type);
......@@ -148,8 +165,8 @@ class Metaspace : public CHeapObj<mtClass> {
size_t used_bytes_slow(MetadataType mdtype) const;
size_t capacity_bytes_slow(MetadataType mdtype) const;
static Metablock* allocate(ClassLoaderData* loader_data, size_t size,
bool read_only, MetadataType mdtype, TRAPS);
static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size,
bool read_only, MetaspaceObj::Type type, TRAPS);
void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
MetaWord* expand_and_allocate(size_t size,
......@@ -166,6 +183,13 @@ class Metaspace : public CHeapObj<mtClass> {
void print_on(outputStream* st) const;
// Debugging support
void verify();
class AllocRecordClosure : public StackObj {
public:
virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0;
};
void iterate(AllocRecordClosure *closure);
};
class MetaspaceAux : AllStatic {
......
......@@ -243,6 +243,147 @@ public:
bool reading() const { return false; }
};
// This is for dumping detailed statistics for the allocations
// in the shared spaces.
class DumpAllocClosure : public Metaspace::AllocRecordClosure {
public:
// Here's poor man's enum inheritance
#define SHAREDSPACE_OBJ_TYPES_DO(f) \
METASPACE_OBJ_TYPES_DO(f) \
f(SymbolHashentry) \
f(SymbolBuckets) \
f(Other)
#define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type,
#define SHAREDSPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
enum Type {
// Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_DECLARE)
_number_of_types
};
static const char * type_name(Type type) {
switch(type) {
SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_NAME_CASE)
default:
ShouldNotReachHere();
return NULL;
}
}
public:
enum {
RO = 0,
RW = 1
};
int _counts[2][_number_of_types];
int _bytes [2][_number_of_types];
int _which;
DumpAllocClosure() {
memset(_counts, 0, sizeof(_counts));
memset(_bytes, 0, sizeof(_bytes));
};
void iterate_metaspace(Metaspace* space, int which) {
assert(which == RO || which == RW, "sanity");
_which = which;
space->iterate(this);
}
virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) {
assert(int(type) >= 0 && type < MetaspaceObj::_number_of_types, "sanity");
_counts[_which][type] ++;
_bytes [_which][type] += byte_size;
}
void dump_stats(int ro_all, int rw_all, int md_all, int mc_all);
};
void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all) {
rw_all += (md_all + mc_all); // md and mc are all mapped Read/Write
int other_bytes = md_all + mc_all;
// Calculate size of data that was not allocated by Metaspace::allocate()
int symbol_count = _counts[RO][MetaspaceObj::SymbolType];
int symhash_bytes = symbol_count * sizeof (HashtableEntry<Symbol*, mtSymbol>);
int symbuck_count = SymbolTable::the_table()->table_size();
int symbuck_bytes = symbuck_count * sizeof(HashtableBucket<mtSymbol>);
_counts[RW][SymbolHashentryType] = symbol_count;
_bytes [RW][SymbolHashentryType] = symhash_bytes;
other_bytes -= symhash_bytes;
_counts[RW][SymbolBucketsType] = symbuck_count;
_bytes [RW][SymbolBucketsType] = symbuck_bytes;
other_bytes -= symbuck_bytes;
// TODO: count things like dictionary, vtable, etc
_bytes[RW][OtherType] = other_bytes;
// prevent divide-by-zero
if (ro_all < 1) {
ro_all = 1;
}
if (rw_all < 1) {
rw_all = 1;
}
int all_ro_count = 0;
int all_ro_bytes = 0;
int all_rw_count = 0;
int all_rw_bytes = 0;
const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f";
const char *sep = "--------------------+---------------------------+---------------------------+--------------------------";
const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %";
tty->print_cr("Detailed metadata info (rw includes md and mc):");
tty->print_cr(hdr);
tty->print_cr(sep);
for (int type = 0; type < int(_number_of_types); type ++) {
const char *name = type_name((Type)type);
int ro_count = _counts[RO][type];
int ro_bytes = _bytes [RO][type];
int rw_count = _counts[RW][type];
int rw_bytes = _bytes [RW][type];
int count = ro_count + rw_count;
int bytes = ro_bytes + rw_bytes;
double ro_perc = 100.0 * double(ro_bytes) / double(ro_all);
double rw_perc = 100.0 * double(rw_bytes) / double(rw_all);
double perc = 100.0 * double(bytes) / double(ro_all + rw_all);
tty->print_cr(fmt, name,
ro_count, ro_bytes, ro_perc,
rw_count, rw_bytes, rw_perc,
count, bytes, perc);
all_ro_count += ro_count;
all_ro_bytes += ro_bytes;
all_rw_count += rw_count;
all_rw_bytes += rw_bytes;
}
int all_count = all_ro_count + all_rw_count;
int all_bytes = all_ro_bytes + all_rw_bytes;
double all_ro_perc = 100.0 * double(all_ro_bytes) / double(ro_all);
double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all);
double all_perc = 100.0 * double(all_bytes) / double(ro_all + rw_all);
tty->print_cr(sep);
tty->print_cr(fmt, "Total",
all_ro_count, all_ro_bytes, all_ro_perc,
all_rw_count, all_rw_bytes, all_rw_perc,
all_count, all_bytes, all_perc);
assert(all_ro_bytes == ro_all, "everything should have been counted");
assert(all_rw_bytes == rw_all, "everything should have been counted");
}
// Populate the shared space.
......@@ -454,6 +595,14 @@ void VM_PopulateDumpSharedSpace::doit() {
mapinfo->close();
memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
if (PrintSharedSpaces) {
DumpAllocClosure dac;
dac.iterate_metaspace(_loader_data->ro_metaspace(), DumpAllocClosure::RO);
dac.iterate_metaspace(_loader_data->rw_metaspace(), DumpAllocClosure::RW);
dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes));
}
}
static void link_shared_classes(Klass* obj, TRAPS) {
......
......@@ -33,7 +33,7 @@
// Allocate annotations in metadata area
Annotations* Annotations::allocate(ClassLoaderData* loader_data, TRAPS) {
return new (loader_data, size(), true, THREAD) Annotations();
return new (loader_data, size(), true, MetaspaceObj::AnnotationType, THREAD) Annotations();
}
// helper
......
......@@ -40,7 +40,7 @@ ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
MethodType method_type,
TRAPS) {
int size = ConstMethod::size(byte_code_size, sizes);
return new (loader_data, size, true, THREAD) ConstMethod(
return new (loader_data, size, true, MetaspaceObj::ConstMethodType, THREAD) ConstMethod(
byte_code_size, sizes, method_type, size);
}
......
......@@ -55,7 +55,7 @@ ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, T
// the resolved_references array, which is recreated at startup time.
// But that could be moved to InstanceKlass (although a pain to access from
// assembly code). Maybe it could be moved to the cpCache which is RW.
return new (loader_data, size, false, THREAD) ConstantPool(tags);
return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
}
ConstantPool::ConstantPool(Array<u1>* tags) {
......
......@@ -542,7 +542,8 @@ ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
const intStack& invokedynamic_map, TRAPS) {
int size = ConstantPoolCache::size(length);
return new (loader_data, size, false, THREAD) ConstantPoolCache(length, index_map, invokedynamic_map);
return new (loader_data, size, false, MetaspaceObj::ConstantPoolCacheType, THREAD)
ConstantPoolCache(length, index_map, invokedynamic_map);
}
void ConstantPoolCache::initialize(const intArray& inverse_index_map,
......
......@@ -140,7 +140,7 @@ Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) {
return Metaspace::allocate(loader_data, word_size, /*read_only*/false,
Metaspace::ClassType, CHECK_NULL);
MetaspaceObj::ClassType, CHECK_NULL);
}
Klass::Klass() {
......
......@@ -74,7 +74,7 @@ Method* Method::allocate(ClassLoaderData* loader_data,
int size = Method::size(access_flags.is_native());
return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
return new (loader_data, size, false, MetaspaceObj::MethodType, THREAD) Method(cm, access_flags, size);
}
Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
......
......@@ -26,7 +26,7 @@
#include "runtime/thread.inline.hpp"
MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
return new(loader_data, size(), false, THREAD) MethodCounters();
return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters();
}
void MethodCounters::clear_counters() {
......
......@@ -388,7 +388,8 @@ void ArgInfoData::print_data_on(outputStream* st) {
MethodData* MethodData::allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS) {
int size = MethodData::compute_allocation_size_in_words(method);
return new (loader_data, size, false, THREAD) MethodData(method(), size, CHECK_NULL);
return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
MethodData(method(), size, CHECK_NULL);
}
int MethodData::bytecode_cell_count(Bytecodes::Code code) {
......
......@@ -55,7 +55,7 @@ void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRA
address res;
int alloc_size = size(len)*HeapWordSize;
res = (address) Metaspace::allocate(loader_data, size(len), true,
Metaspace::NonClassType, CHECK_NULL);
MetaspaceObj::SymbolType, CHECK_NULL);
return res;
}
......
......@@ -1349,12 +1349,11 @@ bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp,
CHECK_0);
}
finalize_operands_merge(*merge_cp_p, THREAD);
RC_TRACE_WITH_THREAD(0x00020000, THREAD,
("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
*merge_cp_length_p, scratch_i, _index_map_count));
}
finalize_operands_merge(*merge_cp_p, THREAD);
return true;
} // end merge_constant_pools()
......
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -44,8 +44,6 @@
#include "runtime/signature.hpp"
#include "runtime/vframe.hpp"
#define JAVA_1_5_VERSION 49
static void trace_class_resolution(Klass* to_class) {
ResourceMark rm;
int line_number = -1;
......@@ -375,7 +373,7 @@ arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop di
}
}
klass = klass->array_klass(dim, CHECK_NULL);
oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD);
oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
assert(obj->is_array(), "just checking");
return arrayOop(obj);
}
......@@ -507,9 +505,11 @@ bool Reflection::can_relax_access_check_for(
under_host_klass(accessee_ik, accessor))
return true;
if (RelaxAccessControlCheck ||
(accessor_ik->major_version() < JAVA_1_5_VERSION &&
accessee_ik->major_version() < JAVA_1_5_VERSION)) {
if ((RelaxAccessControlCheck &&
accessor_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION &&
accessee_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION) ||
(accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION &&
accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) {
return classloader_only &&
Verifier::relax_verify_for(accessor_ik->class_loader()) &&
accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
......@@ -817,6 +817,10 @@ oop Reflection::new_constructor(methodHandle method, TRAPS) {
typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
}
if (java_lang_reflect_Constructor::has_type_annotations_field()) {
typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL);
java_lang_reflect_Constructor::set_type_annotations(ch(), an_oop);
}
return ch();
}
......
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -320,7 +320,7 @@ protected:
void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) {
size_t word_size = Array::size(length);
return (void*) Metaspace::allocate(loader_data, word_size, read_only,
Metaspace::NonClassType, CHECK_NULL);
MetaspaceObj::array_type(sizeof(T)), CHECK_NULL);
}
static size_t byte_sizeof(int length) { return sizeof(Array<T>) + MAX2(length - 1, 0) * sizeof(T); }
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8015436
* @summary the IK _initial_method_idnum value must be adjusted if overpass methods are added
* @run main Test8015436
*
*/
/*
* The test checks that a MemberName for the defaultMethod() is cached in
* the class MemberNameTable without a crash in the VM fastdebug mode.
* The original issue was that the InstanceKlass _initial_method_idnum was
* not adjusted properly when the overpass methods are added to the class.
* The expected/correct behavior: The test does not crash nor throw any exceptions.
* All the invocations of the defaultMethod() must be completed successfully.
*/
import java.lang.invoke.*;
interface InterfaceWithDefaultMethod {
public void someMethod();
default public void defaultMethod(String str){
System.out.println("defaultMethod() " + str);
}
}
public class Test8015436 implements InterfaceWithDefaultMethod {
@Override
public void someMethod() {
System.out.println("someMethod() invoked");
}
public static void main(String[] args) throws Throwable {
Test8015436 testObj = new Test8015436();
testObj.someMethod();
testObj.defaultMethod("invoked directly");
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(void.class, String.class);
MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt);
mh.invokeExact(testObj, "invoked via a MethodHandle");
}
}
/*
* A successful execution gives the output:
* someMethod() invoked
* defaultMethod() invoked directly
* defaultMethod() invoked via a MethodHandle
*/
......@@ -23,7 +23,7 @@
/*
* @test
* @bug 8007320
* @bug 8007320 8014709
* @summary Test all optional fields in ConstMethod
* @compile -g -parameters ConstMethodTest.java
* @run main ConstMethodTest
......@@ -74,6 +74,11 @@ class OkException extends RuntimeException {};
@MyAnnotation(name="someName", value = "Hello World")
public class ConstMethodTest {
public @TypeAnno("constructor") ConstMethodTest() { }
public ConstMethodTest(int i) {
// needs a second unannotated constructor
}
private static void check(boolean b) {
if (!b)
......@@ -139,10 +144,26 @@ public class ConstMethodTest {
}
}
private static void testConstructor() throws Exception {
for (Constructor c : ConstMethodTest.class.getDeclaredConstructors()) {
Annotation[] aa = c.getAnnotatedReturnType().getAnnotations();
if (c.getParameterTypes().length == 1) { // should be un-annotated
check(aa.length == 0);
} else if (c.getParameterTypes().length == 0) { //should be annotated
check(aa.length == 1);
check(((TypeAnno)aa[0]).value().equals("constructor"));
} else {
//should not happen
check(false);
}
}
}
public static void main(java.lang.String[] unused) throws Throwable {
// pass 5 so kitchenSinkFunc is instantiated with an int
kitchenSinkFunc("parameter", "param2", 5);
test1();
testConstructor();
}
};
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test MultiAllocateNullCheck
* @bug 6726963
* @summary multi_allocate() call does not CHECK_NULL and causes crash in fastdebug bits
* @run main/othervm -Xmx32m MultiAllocateNullCheck
*/
import java.lang.reflect.Array;
public class MultiAllocateNullCheck {
public static void main(String[] args) throws Exception {
Object x = null;
try
{
x = Array.newInstance(String.class, new int[]
{Integer.MAX_VALUE, Integer.MAX_VALUE});
System.out.println("Array was created");
} catch (OutOfMemoryError e) {
System.out.println("Out of memory occured, which is OK in this case");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册