< prev index next >
src/hotspot/share/classfile/classFileParser.cpp
Print this page
@@ -494,37 +494,11 @@
class_index, CHECK);
Symbol* const name = cp->symbol_at(class_index);
const unsigned int name_len = name->utf8_length();
- // check explicitly for ;Qjava/lang/__Value;
- if (name_len == 20 &&
- name->equals(";Qjava/lang/__Value;")) {
- cp->symbol_at_put(class_index, vmSymbols::java_lang____Value());
- cp->unresolved_value_type_at_put(index, class_index, num_klasses++);
- } else if (EnableValhalla || EnableMVT) {
- const char* derive_vt_classname_postfix = "$Value;";
- // check for a value type
- // check for name > 3 to rule out ";Q;" where no name is present
- // check for name = 9 to rule out ";Q$Value;" where no name is present for EnableMVT
- if (name_len != 0 &&
- name_len > 3 &&
- name->starts_with(";Q") &&
- ((EnableValhalla && (name->byte_at(name_len-1) == ';')) ||
- (EnableMVT &&
- ClassLoader::string_ends_with(name->as_utf8(), derive_vt_classname_postfix) &&
- name_len != 9))) {
- Symbol* const strippedsym = SymbolTable::new_symbol(name, 2, name_len-1, CHECK);
- assert(strippedsym != NULL, "failure to create value type stripped name");
- cp->symbol_at_put(class_index, strippedsym);
- cp->unresolved_value_type_at_put(index, class_index, num_klasses++);
- } else {
cp->unresolved_klass_at_put(index, class_index, num_klasses++);
- }
- } else {
- cp->unresolved_klass_at_put(index, class_index, num_klasses++);
- }
break;
}
case JVM_CONSTANT_ValueIndex: {
const int class_index = cp->value_type_index_at(index);
check_property(valid_symbol_at(class_index),
@@ -1101,11 +1075,10 @@
_method_LambdaForm_Hidden,
_method_HotSpotIntrinsicCandidate,
_jdk_internal_vm_annotation_Contended,
_field_Stable,
_jdk_internal_vm_annotation_ReservedStackAccess,
- _jdk_incubator_mvt_ValueCapableClass,
_annotation_LIMIT
};
const Location _location;
int _annotations_present;
u2 _contended_group;
@@ -1137,12 +1110,10 @@
bool is_contended() const { return has_annotation(_jdk_internal_vm_annotation_Contended); }
void set_stable(bool stable) { set_annotation(_field_Stable); }
bool is_stable() const { return has_annotation(_field_Stable); }
-
- bool is_value_capable_class() const { return has_annotation(_jdk_incubator_mvt_ValueCapableClass); }
};
// This class also doubles as a holder for metadata cleanup.
class ClassFileParser::FieldAnnotationCollector : public AnnotationCollector {
private:
@@ -1491,17 +1462,17 @@
STATIC_OOP, // Oops
STATIC_BYTE, // Boolean, Byte, char
STATIC_SHORT, // shorts
STATIC_WORD, // ints
STATIC_DOUBLE, // aligned long or double
- STATIC_VALUETYPE, // Value types
+ STATIC_FLATTENABLE, // flattenable field
NONSTATIC_OOP,
NONSTATIC_BYTE,
NONSTATIC_SHORT,
NONSTATIC_WORD,
NONSTATIC_DOUBLE,
- NONSTATIC_VALUETYPE,
+ NONSTATIC_FLATTENABLE,
MAX_FIELD_ALLOCATION_TYPE,
BAD_ALLOCATION_TYPE = -1
};
static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = {
@@ -1517,11 +1488,10 @@
NONSTATIC_SHORT, // T_SHORT = 9,
NONSTATIC_WORD, // T_INT = 10,
NONSTATIC_DOUBLE, // T_LONG = 11,
NONSTATIC_OOP, // T_OBJECT = 12,
NONSTATIC_OOP, // T_ARRAY = 13,
- NONSTATIC_VALUETYPE, // T_VALUETYPE = 14,
BAD_ALLOCATION_TYPE, // T_VOID = 15,
BAD_ALLOCATION_TYPE, // T_ADDRESS = 16,
BAD_ALLOCATION_TYPE, // T_NARROWOOP = 17,
BAD_ALLOCATION_TYPE, // T_METADATA = 18,
BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 19,
@@ -1539,11 +1509,10 @@
STATIC_SHORT, // T_SHORT = 9,
STATIC_WORD, // T_INT = 10,
STATIC_DOUBLE, // T_LONG = 11,
STATIC_OOP, // T_OBJECT = 12,
STATIC_OOP, // T_ARRAY = 13,
- STATIC_VALUETYPE, // T_VALUETYPE = 14,
BAD_ALLOCATION_TYPE, // T_VOID = 15,
BAD_ALLOCATION_TYPE, // T_ADDRESS = 16,
BAD_ALLOCATION_TYPE, // T_NARROWOOP = 17,
BAD_ALLOCATION_TYPE, // T_METADATA = 18,
BAD_ALLOCATION_TYPE, // T_NARROWKLASS = 19,
@@ -1657,12 +1626,12 @@
check_property(valid_symbol_at(signature_index),
"Invalid constant pool index %u for field signature in class file %s",
signature_index, CHECK);
const Symbol* const sig = cp->symbol_at(signature_index);
verify_legal_field_signature(name, sig, CHECK);
- if (sig->starts_with("Q")) {
- _has_value_fields = true;
+ if (access_flags.is_flattenable()) {
+ _has_flattenable_fields = true;
}
u2 constantvalue_index = 0;
bool is_synthetic = false;
u2 generic_signature_index = 0;
@@ -1771,13 +1740,13 @@
if (is_concrete_value_type) {
index = length + num_injected;
FieldInfo* const field = FieldInfo::from_field_array(fa, index);
field->initialize(JVM_ACC_FIELD_INTERNAL | JVM_ACC_STATIC,
vmSymbols::default_value_name_enum,
- vmSymbols::java_lang___Value_signature_enum,
+ vmSymbols::java_lang_Object_enum,
0);
- const BasicType type = FieldType::basic_type(vmSymbols::java_lang___Value_signature());
+ const BasicType type = FieldType::basic_type(vmSymbols::object_signature());
const FieldAllocationType atype = fac->update(true, type);
field->set_allocation_type(atype);
index++;
}
@@ -2204,16 +2173,10 @@
case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ReservedStackAccess_signature): {
if (_location != _in_method) break; // only allow for methods
if (RestrictReservedStack && !privileged) break; // honor privileges
return _jdk_internal_vm_annotation_ReservedStackAccess;
}
- case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_incubator_mvt_ValueCapableClass_signature) : {
- if (_location != _in_class) {
- break;
- }
- return _jdk_incubator_mvt_ValueCapableClass;
- }
default: {
break;
}
}
return AnnotationCollector::_unknown;
@@ -2252,13 +2215,10 @@
}
void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
assert(ik != NULL, "invariant");
ik->set_is_contended(is_contended());
- if (is_value_capable_class()) {
- ik->set_has_vcc_annotation();
- }
}
#define MAX_ARGS_SIZE 255
#define MAX_CODE_SIZE 65535
#define INITIAL_MAX_LVT_NUMBER 256
@@ -3976,11 +3936,11 @@
// Calculate the starting byte offsets
int next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields();
// Value types in static fields are not embedded, they are handled with oops
int next_static_double_offset = next_static_oop_offset +
- ((fac->count[STATIC_OOP] + fac->count[STATIC_VALUETYPE]) * heapOopSize);
+ ((fac->count[STATIC_OOP] + fac->count[STATIC_FLATTENABLE]) * heapOopSize);
if ( fac->count[STATIC_DOUBLE] &&
(Universe::field_type_should_be_aligned(T_DOUBLE) ||
Universe::field_type_should_be_aligned(T_LONG)) ) {
next_static_double_offset = align_up(next_static_double_offset, BytesPerLong);
}
@@ -3997,11 +3957,11 @@
// First field of value types is aligned on a long boundary in order to ease
// in-lining of value types (with header removal) in packed arrays and
// flatten value types
int initial_value_type_padding = 0;
- if (is_value_type() || is_value_capable_class()) {
+ if (is_value_type()) {
int old = nonstatic_fields_start;
nonstatic_fields_start = align_up(nonstatic_fields_start, BytesPerLong);
initial_value_type_padding = nonstatic_fields_start - old;
}
@@ -4013,11 +3973,11 @@
if (is_contended_class) {
next_nonstatic_field_offset += ContendedPaddingWidth;
}
// Temporary value types restrictions
- if (is_value_type() || is_value_capable_class()) {
+ if (is_value_type()) {
if (is_contended_class) {
throwValueTypeLimitation(THREAD_AND_LOCATION, "Value Types do not support @Contended annotation yet");
return;
}
}
@@ -4037,33 +3997,34 @@
int* nonstatic_value_type_indexes = NULL;
Klass** nonstatic_value_type_klasses = NULL;
unsigned int value_type_oop_map_count = 0;
int not_flattened_value_types = 0;
- int max_nonstatic_value_type = fac->count[NONSTATIC_VALUETYPE] + 1;
+ int max_nonstatic_value_type = fac->count[NONSTATIC_FLATTENABLE] + 1;
nonstatic_value_type_indexes = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, int,
max_nonstatic_value_type);
for (int i = 0; i < max_nonstatic_value_type; i++) {
nonstatic_value_type_indexes[i] = -1;
}
nonstatic_value_type_klasses = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, Klass*,
max_nonstatic_value_type);
for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) {
- if (fs.allocation_type() == STATIC_VALUETYPE) {
+ if (fs.allocation_type() == STATIC_FLATTENABLE) {
static_value_type_count++;
- } else if (fs.allocation_type() == NONSTATIC_VALUETYPE) {
+ } else if (fs.allocation_type() == NONSTATIC_FLATTENABLE) {
Symbol* signature = fs.signature();
Klass* klass = SystemDictionary::resolve_or_fail(signature,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
assert(klass->access_flags().is_value_type(), "Value type expected");
ValueKlass* vk = ValueKlass::cast(klass);
// Conditions to apply flattening or not should be defined in a single place
- if ((ValueFieldMaxFlatSize < 0) || vk->size_helper() <= ValueFieldMaxFlatSize) {
+ if ( false && // Currently disabling flattening
+ ((ValueFieldMaxFlatSize < 0) || vk->size_helper() <= ValueFieldMaxFlatSize)) {
nonstatic_value_type_indexes[nonstatic_value_type_count] = fs.index();
nonstatic_value_type_klasses[nonstatic_value_type_count] = klass;
nonstatic_value_type_count++;
ValueKlass* vklass = ValueKlass::cast(klass);
@@ -4082,24 +4043,22 @@
nonstatic_oop_count += not_flattened_value_types;
// Total non-static fields count, including every contended field
unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
- fac->count[NONSTATIC_OOP] + fac->count[NONSTATIC_VALUETYPE];
+ fac->count[NONSTATIC_OOP] + fac->count[NONSTATIC_FLATTENABLE];
const bool super_has_nonstatic_fields =
(_super_klass != NULL && _super_klass->has_nonstatic_fields());
const bool has_nonstatic_fields =
super_has_nonstatic_fields || (nonstatic_fields_count != 0);
const bool has_nonstatic_value_fields = nonstatic_value_type_count > 0;
if (is_value_type() && (!has_nonstatic_fields)) {
// There are a number of fixes required throughout the type system and JIT
- if (class_name() != vmSymbols::java_lang____Value()) {
throwValueTypeLimitation(THREAD_AND_LOCATION, "Value Types do not support zero instance size yet");
}
- }
// Prepare list of oops for oop map generation.
//
// "offset" and "count" lists are describing the set of contiguous oop
// regions. offset[i] is the start of the i-th region, which then has
@@ -4276,11 +4235,11 @@
const FieldAllocationType atype = (const FieldAllocationType) fs.allocation_type();
// pack the rest of the fields
switch (atype) {
// Value types in static fields are handled with oops
- case STATIC_VALUETYPE: // Fallthrough
+ case STATIC_FLATTENABLE: // Fallthrough
case STATIC_OOP:
real_offset = next_static_oop_offset;
next_static_oop_offset += heapOopSize;
break;
case STATIC_BYTE:
@@ -4297,11 +4256,11 @@
break;
case STATIC_DOUBLE:
real_offset = next_static_double_offset;
next_static_double_offset += BytesPerLong;
break;
- case NONSTATIC_VALUETYPE:
+ case NONSTATIC_FLATTENABLE:
if (fs.is_flatten()) {
Klass* klass = nonstatic_value_type_klasses[next_value_type_index];
assert(klass != NULL, "Klass should have been loaded and resolved earlier");
assert(klass->access_flags().is_value_type(),"Must be a value type");
ValueKlass* vklass = ValueKlass::cast(klass);
@@ -4441,11 +4400,11 @@
real_offset = next_nonstatic_padded_offset;
next_nonstatic_padded_offset += BytesPerLong;
break;
// Value types in static fields are handled with oops
- case NONSTATIC_VALUETYPE:
+ case NONSTATIC_FLATTENABLE:
throwValueTypeLimitation(THREAD_AND_LOCATION,
"@Contended annotation not supported for value types yet", fs.name(), fs.signature());
return;
case NONSTATIC_OOP:
@@ -4485,11 +4444,11 @@
// Entire class is contended, pad in the back.
// This helps to alleviate memory contention effects for subclass fields
// and/or adjacent object.
if (is_contended_class) {
- assert(!is_value_type() && !is_value_capable_class(), "@Contended not supported for value types yet");
+ assert(!is_value_type(), "@Contended not supported for value types yet");
next_nonstatic_padded_offset += ContendedPaddingWidth;
}
int notaligned_nonstatic_fields_end;
if (nonstatic_value_type_count != 0) {
@@ -4497,11 +4456,11 @@
} else {
notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
}
int nonstatic_field_sz_align = heapOopSize;
- if (is_value_type() || is_value_capable_class()) {
+ if (is_value_type()) {
if ((notaligned_nonstatic_fields_end - nonstatic_fields_start) > heapOopSize) {
nonstatic_field_sz_align = BytesPerLong; // value copy of fields only uses jlong copy
}
}
int nonstatic_fields_end = align_up(notaligned_nonstatic_fields_end, nonstatic_field_sz_align);
@@ -4656,11 +4615,11 @@
defining_loader_data->record_dependency(local_interfaces->at(i), CHECK);
}
}
for(int i = 0; i < defined_klass->java_fields_count(); i++) {
- if (defined_klass->field_signature(i)->starts_with("Q") && (((defined_klass->field_access_flags(i) & JVM_ACC_STATIC)) == 0)) {
+ if ((defined_klass->field_access_flags(i) & JVM_ACC_FLATTENABLE) != 0) {
const Klass* klass = defined_klass->get_value_field_klass(i);
defining_loader_data->record_dependency(klass, CHECK);
}
}
}
@@ -5628,11 +5587,11 @@
log_info(class, fingerprint)("%s : expected = " PTR64_FORMAT " actual = " PTR64_FORMAT,
ik->external_name(), aot_fp, _stream->compute_fingerprint());
}
}
- if (ik->is_value() && (ik->name() != vmSymbols::java_lang____Value())) {
+ if (ik->is_value()) {
ValueKlass* vk = ValueKlass::cast(ik);
oop val = ik->allocate_instance(CHECK_NULL);
vk->set_default_value(val);
}
@@ -5658,11 +5617,11 @@
// Not yet: supers are done below to support the new subtype-checking fields
ik->set_class_loader_data(_loader_data);
ik->set_nonstatic_field_size(_field_info->nonstatic_field_size);
ik->set_has_nonstatic_fields(_field_info->has_nonstatic_fields);
assert(_fac != NULL, "invariant");
- ik->set_static_oop_field_count(_fac->count[STATIC_OOP] + _fac->count[STATIC_VALUETYPE]);
+ ik->set_static_oop_field_count(_fac->count[STATIC_OOP] + _fac->count[STATIC_FLATTENABLE]);
// this transfers ownership of a lot of arrays from
// the parser onto the InstanceKlass*
apply_parsed_class_metadata(ik, _java_fields_count, CHECK);
@@ -5797,41 +5756,34 @@
ValueKlass* vk = ValueKlass::cast(ik);
vk->set_if_bufferable();
vk->initialize_calling_convention();
}
- // Valhalla shady value type conversion
- if (_parsed_annotations->is_value_capable_class()) {
- ik->create_value_capable_class(Handle(THREAD, _loader_data->class_loader()),
- _protection_domain, CHECK);
- }
-
// Add read edges to the unnamed modules of the bootstrap and app class loaders.
if (changed_by_loadhook && !module_handle.is_null() && module_entry->is_named() &&
!module_entry->has_default_read_edges()) {
if (!module_entry->set_has_default_read_edges()) {
// We won a potential race
JvmtiExport::add_default_read_edges(module_handle, THREAD);
}
}
int nfields = ik->java_fields_count();
- if (ik->is_value() && (ik->name() != vmSymbols::java_lang____Value())) nfields++;
+ if (ik->is_value()) nfields++;
for(int i = 0; i < nfields; i++) {
- if (ik->field_signature(i)->starts_with("Q")) {
- if ((((ik->field_access_flags(i) & JVM_ACC_STATIC)) == 0)) {
+ if (ik->field_access_flags(i) & JVM_ACC_FLATTENABLE) {
Klass* klass = SystemDictionary::resolve_or_fail(ik->field_signature(i),
Handle(THREAD, ik->class_loader()),
Handle(THREAD, ik->protection_domain()), true, CHECK);
assert(klass != NULL, "Sanity check");
assert(klass->access_flags().is_value_type(), "Value type expected");
ik->set_value_field_klass(i, klass);
- } else if (is_value_type() && ((ik->field_access_flags(i) & JVM_ACC_FIELD_INTERNAL) != 0)) {
+ } else if (is_value_type() && ((ik->field_access_flags(i) & JVM_ACC_FIELD_INTERNAL) != 0)
+ && ((ik->field_access_flags(i) & JVM_ACC_STATIC) != 0)) {
ValueKlass::cast(ik)->set_default_value_offset(ik->field_offset(i));
}
}
- }
// Update the loader_data graph.
record_defined_class_dependencies(ik, CHECK);
ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);
@@ -6001,11 +5953,11 @@
_has_final_method(false),
_has_finalizer(false),
_has_empty_finalizer(false),
_has_vanilla_constructor(false),
_max_bootstrap_specifier_index(-1),
- _has_value_fields(false) {
+ _has_flattenable_fields(false) {
_class_name = name != NULL ? name : vmSymbols::unknown_class_name();
assert(THREAD->is_Java_thread(), "invariant");
assert(_loader_data != NULL, "invariant");
@@ -6347,11 +6299,11 @@
// Fields (offsets are filled in later)
_fac = new FieldAllocationCount();
parse_fields(stream,
_access_flags.is_interface(),
- _access_flags.is_value_type() && (_class_name != vmSymbols::java_lang____Value()),
+ _access_flags.is_value_type(),
_fac,
cp,
cp_size,
&_java_fields_count,
CHECK);
@@ -6442,30 +6394,20 @@
_super_klass->external_name()
);
return;
}
- // For a java/lang/__Value super class, the class inheriting, must be a value class
- if ((EnableValhalla || EnableMVT) &&
- _super_klass->name() == vmSymbols::java_lang____Value()) {
- guarantee_property((_access_flags.get_flags() & JVM_ACC_VALUE) != 0,
- "Only a value class can inherit from java/lang/__Value",
- CHECK);
- }
-
- // For a value class, only java/lang/__Value is an acceptable super class
+ // For a value class, only java/lang/Object is an acceptable super class
if ((EnableValhalla || EnableMVT) &&
_access_flags.get_flags() & JVM_ACC_VALUE) {
- guarantee_property(_super_klass->name() == vmSymbols::java_lang____Value(),
- "Value class can only inherit java/lang/__Value",
+ guarantee_property(_super_klass->name() == vmSymbols::java_lang_Object(),
+ "Value class can only inherit java/lang/Object",
CHECK);
}
// Make sure super class is not final
- if (_super_klass->is_final()
- && !(_super_klass->name() == vmSymbols::java_lang____Value()
- && (_access_flags.get_flags() & JVM_ACC_VALUE))) {
+ if (_super_klass->is_final()) {
THROW_MSG(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class");
}
}
// Compute the transitive list of all unique interfaces implemented by this class
@@ -6538,14 +6480,10 @@
assert(_stream != NULL, "invariant");
return _stream->clone();
}
-bool ClassFileParser::is_value_capable_class() const {
- return _parsed_annotations->is_value_capable_class();
-}
-
// ----------------------------------------------------------------------------
// debugging
#ifdef ASSERT
< prev index next >