提交 5bd2e031 编写于 作者: T twisti

6994630: java/lang/instrument/IsModifiableClassAgent.java fails with -XX:+EnableInvokeDynamic

Summary: The logic of ClassFileParser::java_dyn_MethodHandle_fix_pre needs to take care of an already changed vmentry signature.
Reviewed-by: never, jrose
上级 180978b9
/* /*
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -2505,18 +2505,6 @@ void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_pt ...@@ -2505,18 +2505,6 @@ void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_pt
// the check for the "discovered" field should issue a warning if // the check for the "discovered" field should issue a warning if
// the field is not found. For 1.6 this code should be issue a // the field is not found. For 1.6 this code should be issue a
// fatal error if the "discovered" field is not found. // fatal error if the "discovered" field is not found.
//
// Increment fac.nonstatic_oop_count so that the start of the
// next type of non-static oops leaves room for the fake oop.
// Do not increment next_nonstatic_oop_offset so that the
// fake oop is place after the java.lang.ref.Reference oop
// fields.
//
// Check the fields in java.lang.ref.Reference for the "discovered"
// field. If it is not present, artifically create a field for it.
// This allows this VM to run on early JDK where the field is not
// present.
// //
// Increment fac.nonstatic_oop_count so that the start of the // Increment fac.nonstatic_oop_count so that the start of the
// next type of non-static oops leaves room for the fake oop. // next type of non-static oops leaves room for the fake oop.
...@@ -2663,7 +2651,7 @@ void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_pt ...@@ -2663,7 +2651,7 @@ void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_pt
// Force MethodHandle.vmentry to be an unmanaged pointer. // Force MethodHandle.vmentry to be an unmanaged pointer.
// There is no way for a classfile to express this, so we must help it. // There is no way for a classfile to express this, so we must help it.
void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp, void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
typeArrayHandle* fields_ptr, typeArrayHandle fields,
FieldAllocationCount *fac_ptr, FieldAllocationCount *fac_ptr,
TRAPS) { TRAPS) {
// Add fake fields for java.dyn.MethodHandle instances // Add fake fields for java.dyn.MethodHandle instances
...@@ -2687,41 +2675,45 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp, ...@@ -2687,41 +2675,45 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
"missing I or J signature (for vmentry) in java.dyn.MethodHandle"); "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
// Find vmentry field and change the signature.
bool found_vmentry = false; bool found_vmentry = false;
for (int i = 0; i < fields->length(); i += instanceKlass::next_offset) {
const int n = (*fields_ptr)()->length(); int name_index = fields->ushort_at(i + instanceKlass::name_index_offset);
for (int i = 0; i < n; i += instanceKlass::next_offset) { int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset);
int name_index = (*fields_ptr)->ushort_at(i + instanceKlass::name_index_offset); int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset);
int sig_index = (*fields_ptr)->ushort_at(i + instanceKlass::signature_index_offset);
int acc_flags = (*fields_ptr)->ushort_at(i + instanceKlass::access_flags_offset);
symbolOop f_name = cp->symbol_at(name_index); symbolOop f_name = cp->symbol_at(name_index);
symbolOop f_sig = cp->symbol_at(sig_index); symbolOop f_sig = cp->symbol_at(sig_index);
if (f_sig == vmSymbols::byte_signature() &&
f_name == vmSymbols::vmentry_name() && if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) {
(acc_flags & JVM_ACC_STATIC) == 0) { if (f_sig == vmSymbols::machine_word_signature()) {
// Adjust the field type from byte to an unmanaged pointer. // If the signature of vmentry is already changed, we're done.
assert(fac_ptr->nonstatic_byte_count > 0, ""); found_vmentry = true;
fac_ptr->nonstatic_byte_count -= 1; break;
}
(*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index); else if (f_sig == vmSymbols::byte_signature()) {
assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64"); // Adjust the field type from byte to an unmanaged pointer.
if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1; assert(fac_ptr->nonstatic_byte_count > 0, "");
else fac_ptr->nonstatic_word_count += 1; fac_ptr->nonstatic_byte_count -= 1;
FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset); fields->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index);
assert(atype == NONSTATIC_BYTE, ""); assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64");
FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD; if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1;
(*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype); else fac_ptr->nonstatic_word_count += 1;
found_vmentry = true; FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
break; assert(atype == NONSTATIC_BYTE, "");
FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD;
fields->ushort_at_put(i + instanceKlass::low_offset, new_atype);
found_vmentry = true;
break;
}
} }
} }
if (!found_vmentry) if (!found_vmentry)
THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
"missing vmentry byte field in java.dyn.MethodHandle"); "missing vmentry byte field in java.dyn.MethodHandle");
} }
...@@ -3082,7 +3074,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -3082,7 +3074,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// adjust the vmentry field declaration in java.dyn.MethodHandle // adjust the vmentry field declaration in java.dyn.MethodHandle
if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) { if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle)); java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
} }
// Add a fake "discovered" field if it is not present // Add a fake "discovered" field if it is not present
......
/* /*
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -151,7 +151,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { ...@@ -151,7 +151,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// Adjust the field allocation counts for java.dyn.MethodHandle to add // Adjust the field allocation counts for java.dyn.MethodHandle to add
// a fake address (void*) field. // a fake address (void*) field.
void java_dyn_MethodHandle_fix_pre(constantPoolHandle cp, void java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
typeArrayHandle* fields_ptr, typeArrayHandle fields,
FieldAllocationCount *fac_ptr, TRAPS); FieldAllocationCount *fac_ptr, TRAPS);
// Format checker methods // Format checker methods
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册