8313435: Clean up unused default methods code
Reviewed-by: kbarrett, iklam
This commit is contained in:
parent
8752d4984a
commit
5c3041ce83
src/hotspot/share/classfile
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2023, 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
|
||||
@ -25,15 +25,22 @@
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "classfile/bytecodeAssembler.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "interpreter/bytecodes.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "utilities/bytes.hpp"
|
||||
|
||||
u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) {
|
||||
u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe, TRAPS) {
|
||||
|
||||
u2 index = _entries.length();
|
||||
// Check for overflow
|
||||
int new_size = _orig->length() + _entries.length();
|
||||
if (new_size > USHRT_MAX) {
|
||||
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "default methods constant pool overflowed");
|
||||
}
|
||||
|
||||
u2 index = checked_cast<u2>(_entries.length());
|
||||
bool created = false;
|
||||
u2* probe = _indices.put_if_absent(bcpe, index, &created);
|
||||
if (created) {
|
||||
@ -41,7 +48,7 @@ u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) {
|
||||
} else {
|
||||
index = *probe;
|
||||
}
|
||||
return index + _orig->length();
|
||||
return checked_cast<u2>(index + _orig->length());
|
||||
}
|
||||
|
||||
ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
|
||||
@ -49,9 +56,10 @@ ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
|
||||
return _orig;
|
||||
}
|
||||
|
||||
int new_size = _orig->length() + _entries.length();
|
||||
ConstantPool* cp = ConstantPool::allocate(
|
||||
_orig->pool_holder()->class_loader_data(),
|
||||
_orig->length() + _entries.length(), CHECK_NULL);
|
||||
new_size, CHECK_NULL);
|
||||
|
||||
cp->set_pool_holder(_orig->pool_holder());
|
||||
constantPoolHandle cp_h(THREAD, cp);
|
||||
@ -114,29 +122,20 @@ void BytecodeAssembler::append(u4 imm_u4) {
|
||||
Bytes::put_Java_u4(_code->adr_at(_code->length() - 4), imm_u4);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::xload(u4 index, u1 onebyteop, u1 twobyteop) {
|
||||
if (index < 4) {
|
||||
_code->append(onebyteop + index);
|
||||
} else {
|
||||
_code->append(twobyteop);
|
||||
_code->append((u2)index);
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeAssembler::dup() {
|
||||
_code->append(Bytecodes::_dup);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::_new(Symbol* sym) {
|
||||
u2 cpool_index = _cp->klass(sym);
|
||||
void BytecodeAssembler::_new(Symbol* sym, TRAPS) {
|
||||
u2 cpool_index = _cp->klass(sym, CHECK);
|
||||
_code->append(Bytecodes::_new);
|
||||
append(cpool_index);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::load_string(Symbol* sym) {
|
||||
u2 cpool_index = _cp->string(sym);
|
||||
void BytecodeAssembler::load_string(Symbol* sym, TRAPS) {
|
||||
u2 cpool_index = _cp->string(sym, CHECK);
|
||||
if (cpool_index < 0x100) {
|
||||
ldc(cpool_index);
|
||||
ldc((u1)cpool_index);
|
||||
} else {
|
||||
ldc_w(cpool_index);
|
||||
}
|
||||
@ -156,111 +155,27 @@ void BytecodeAssembler::athrow() {
|
||||
_code->append(Bytecodes::_athrow);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::iload(u4 index) {
|
||||
xload(index, Bytecodes::_iload_0, Bytecodes::_iload);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::lload(u4 index) {
|
||||
xload(index, Bytecodes::_lload_0, Bytecodes::_lload);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::fload(u4 index) {
|
||||
xload(index, Bytecodes::_fload_0, Bytecodes::_fload);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::dload(u4 index) {
|
||||
xload(index, Bytecodes::_dload_0, Bytecodes::_dload);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::aload(u4 index) {
|
||||
xload(index, Bytecodes::_aload_0, Bytecodes::_aload);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::load(BasicType bt, u4 index) {
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
case T_CHAR:
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT: iload(index); break;
|
||||
case T_FLOAT: fload(index); break;
|
||||
case T_DOUBLE: dload(index); break;
|
||||
case T_LONG: lload(index); break;
|
||||
default:
|
||||
if (is_reference_type(bt)) {
|
||||
aload(index);
|
||||
break;
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeAssembler::checkcast(Symbol* sym) {
|
||||
u2 cpool_index = _cp->klass(sym);
|
||||
_code->append(Bytecodes::_checkcast);
|
||||
append(cpool_index);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::invokespecial(Method* method) {
|
||||
invokespecial(method->klass_name(), method->name(), method->signature());
|
||||
}
|
||||
|
||||
void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig) {
|
||||
u2 methodref_index = _cp->methodref(klss, name, sig);
|
||||
void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig, TRAPS) {
|
||||
u2 methodref_index = _cp->methodref(klss, name, sig, CHECK);
|
||||
_code->append(Bytecodes::_invokespecial);
|
||||
append(methodref_index);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::invokevirtual(Method* method) {
|
||||
invokevirtual(method->klass_name(), method->name(), method->signature());
|
||||
}
|
||||
int BytecodeAssembler::assemble_method_error(BytecodeConstantPool* cp,
|
||||
BytecodeBuffer* buffer,
|
||||
Symbol* errorName,
|
||||
Symbol* message, TRAPS) {
|
||||
|
||||
void BytecodeAssembler::invokevirtual(Symbol* klss, Symbol* name, Symbol* sig) {
|
||||
u2 methodref_index = _cp->methodref(klss, name, sig);
|
||||
_code->append(Bytecodes::_invokevirtual);
|
||||
append(methodref_index);
|
||||
}
|
||||
Symbol* init = vmSymbols::object_initializer_name();
|
||||
Symbol* sig = vmSymbols::string_void_signature();
|
||||
|
||||
void BytecodeAssembler::ireturn() {
|
||||
_code->append(Bytecodes::_ireturn);
|
||||
}
|
||||
BytecodeAssembler assem(buffer, cp);
|
||||
|
||||
void BytecodeAssembler::lreturn() {
|
||||
_code->append(Bytecodes::_lreturn);
|
||||
}
|
||||
assem._new(errorName, CHECK_0);
|
||||
assem.dup();
|
||||
assem.load_string(message, CHECK_0);
|
||||
assem.invokespecial(errorName, init, sig, CHECK_0);
|
||||
assem.athrow();
|
||||
|
||||
void BytecodeAssembler::freturn() {
|
||||
_code->append(Bytecodes::_freturn);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::dreturn() {
|
||||
_code->append(Bytecodes::_dreturn);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::areturn() {
|
||||
_code->append(Bytecodes::_areturn);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::_return() {
|
||||
_code->append(Bytecodes::_return);
|
||||
}
|
||||
|
||||
void BytecodeAssembler::_return(BasicType bt) {
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
case T_CHAR:
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT: ireturn(); break;
|
||||
case T_FLOAT: freturn(); break;
|
||||
case T_DOUBLE: dreturn(); break;
|
||||
case T_LONG: lreturn(); break;
|
||||
case T_VOID: _return(); break;
|
||||
default:
|
||||
if (is_reference_type(bt)) {
|
||||
areturn();
|
||||
break;
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
return 3; // max stack size: [ exception, exception, string ]
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2023, 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
|
||||
@ -132,7 +132,7 @@ class BytecodeConstantPool : ResourceObj {
|
||||
GrowableArray<BytecodeCPEntry> _entries;
|
||||
IndexHash _indices;
|
||||
|
||||
u2 find_or_add(BytecodeCPEntry const& bcpe);
|
||||
u2 find_or_add(BytecodeCPEntry const& bcpe, TRAPS);
|
||||
|
||||
public:
|
||||
|
||||
@ -144,25 +144,30 @@ class BytecodeConstantPool : ResourceObj {
|
||||
return _orig->pool_holder();
|
||||
}
|
||||
|
||||
u2 utf8(Symbol* sym) {
|
||||
return find_or_add(BytecodeCPEntry::utf8(sym));
|
||||
u2 utf8(Symbol* sym, TRAPS) {
|
||||
return find_or_add(BytecodeCPEntry::utf8(sym), THREAD);
|
||||
}
|
||||
|
||||
u2 klass(Symbol* class_name) {
|
||||
return find_or_add(BytecodeCPEntry::klass(utf8(class_name)));
|
||||
u2 klass(Symbol* class_name, TRAPS) {
|
||||
u2 utf8_entry = utf8(class_name, CHECK_0);
|
||||
return find_or_add(BytecodeCPEntry::klass(utf8_entry), THREAD);
|
||||
}
|
||||
|
||||
u2 string(Symbol* str) {
|
||||
return find_or_add(BytecodeCPEntry::string(utf8(str)));
|
||||
u2 string(Symbol* str, TRAPS) {
|
||||
u2 utf8_entry = utf8(str, CHECK_0);
|
||||
return find_or_add(BytecodeCPEntry::string(utf8_entry), THREAD);
|
||||
}
|
||||
|
||||
u2 name_and_type(Symbol* name, Symbol* sig) {
|
||||
return find_or_add(BytecodeCPEntry::name_and_type(utf8(name), utf8(sig)));
|
||||
u2 name_and_type(Symbol* name, Symbol* sig, TRAPS) {
|
||||
u2 utf8_name = utf8(name, CHECK_0);
|
||||
u2 utf8_sig = utf8(sig, CHECK_0);
|
||||
return find_or_add(BytecodeCPEntry::name_and_type(utf8_name, utf8_sig), THREAD);
|
||||
}
|
||||
|
||||
u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig) {
|
||||
return find_or_add(BytecodeCPEntry::methodref(
|
||||
klass(class_name), name_and_type(name, sig)));
|
||||
u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig, TRAPS) {
|
||||
u2 klass_entry = klass(class_name, CHECK_0);
|
||||
u2 type_entry = name_and_type(name, sig, CHECK_0);
|
||||
return find_or_add(BytecodeCPEntry::methodref(klass_entry, type_entry), THREAD);
|
||||
}
|
||||
|
||||
ConstantPool* create_constant_pool(TRAPS) const;
|
||||
@ -179,37 +184,22 @@ class BytecodeAssembler : StackObj {
|
||||
void append(u2 imm_u2);
|
||||
void append(u4 imm_u4);
|
||||
|
||||
void xload(u4 index, u1 quick, u1 twobyte);
|
||||
void athrow();
|
||||
void dup();
|
||||
void invokespecial(Symbol* cls, Symbol* name, Symbol* sig, TRAPS);
|
||||
void ldc(u1 index);
|
||||
void ldc_w(u2 index);
|
||||
void _new(Symbol* sym, TRAPS);
|
||||
void load_string(Symbol* sym, TRAPS);
|
||||
|
||||
public:
|
||||
BytecodeAssembler(BytecodeBuffer* buffer, BytecodeConstantPool* cp)
|
||||
: _code(buffer), _cp(cp) {}
|
||||
|
||||
void aload(u4 index);
|
||||
void areturn();
|
||||
void athrow();
|
||||
void checkcast(Symbol* sym);
|
||||
void dload(u4 index);
|
||||
void dreturn();
|
||||
void dup();
|
||||
void fload(u4 index);
|
||||
void freturn();
|
||||
void iload(u4 index);
|
||||
void invokespecial(Method* method);
|
||||
void invokespecial(Symbol* cls, Symbol* name, Symbol* sig);
|
||||
void invokevirtual(Method* method);
|
||||
void invokevirtual(Symbol* cls, Symbol* name, Symbol* sig);
|
||||
void ireturn();
|
||||
void ldc(u1 index);
|
||||
void ldc_w(u2 index);
|
||||
void lload(u4 index);
|
||||
void lreturn();
|
||||
void _new(Symbol* sym);
|
||||
void _return();
|
||||
|
||||
void load_string(Symbol* sym);
|
||||
void load(BasicType bt, u4 index);
|
||||
void _return(BasicType bt);
|
||||
static int assemble_method_error(BytecodeConstantPool* cp,
|
||||
BytecodeBuffer* buffer,
|
||||
Symbol* errorName,
|
||||
Symbol* message, TRAPS);
|
||||
};
|
||||
|
||||
#endif // SHARE_CLASSFILE_BYTECODEASSEMBLER_HPP
|
||||
|
@ -865,23 +865,6 @@ void DefaultMethods::generate_default_methods(
|
||||
log_debug(defaultmethods)("Default method processing complete");
|
||||
}
|
||||
|
||||
static int assemble_method_error(
|
||||
BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message) {
|
||||
|
||||
Symbol* init = vmSymbols::object_initializer_name();
|
||||
Symbol* sig = vmSymbols::string_void_signature();
|
||||
|
||||
BytecodeAssembler assem(buffer, cp);
|
||||
|
||||
assem._new(errorName);
|
||||
assem.dup();
|
||||
assem.load_string(message);
|
||||
assem.invokespecial(errorName, init, sig);
|
||||
assem.athrow();
|
||||
|
||||
return 3; // max stack size: [ exception, exception, string ]
|
||||
}
|
||||
|
||||
static Method* new_method(
|
||||
BytecodeConstantPool* cp, BytecodeBuffer* bytecodes, Symbol* name,
|
||||
Symbol* sig, AccessFlags flags, int max_stack, int params,
|
||||
@ -901,8 +884,10 @@ static Method* new_method(
|
||||
mt, name, CHECK_NULL);
|
||||
|
||||
m->set_constants(nullptr); // This will get filled in later
|
||||
m->set_name_index(cp->utf8(name));
|
||||
m->set_signature_index(cp->utf8(sig));
|
||||
u2 name_index = cp->utf8(name, CHECK_NULL);
|
||||
m->set_name_index(name_index);
|
||||
u2 sig_index = cp->utf8(sig, CHECK_NULL);
|
||||
m->set_signature_index(sig_index);
|
||||
m->constMethod()->compute_from_signature(sig, flags.is_static());
|
||||
assert(m->size_of_parameters() == params, "should be computed above");
|
||||
m->set_max_stack(max_stack);
|
||||
@ -989,8 +974,8 @@ static void create_defaults_and_exceptions(GrowableArray<EmptyVtableSlot*>* slot
|
||||
} else {
|
||||
buffer->clear();
|
||||
}
|
||||
int max_stack = assemble_method_error(&bpool, buffer,
|
||||
method->get_exception_name(), method->get_exception_message());
|
||||
int max_stack = BytecodeAssembler::assemble_method_error(&bpool, buffer,
|
||||
method->get_exception_name(), method->get_exception_message(), CHECK);
|
||||
AccessFlags flags = accessFlags_from(
|
||||
JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE);
|
||||
Method* m = new_method(&bpool, buffer, slot->name(), slot->signature(),
|
||||
@ -1073,7 +1058,12 @@ static void merge_in_new_methods(InstanceKlass* klass,
|
||||
Array<int>* original_ordering = klass->method_ordering();
|
||||
Array<int>* merged_ordering = Universe::the_empty_int_array();
|
||||
|
||||
int new_size = klass->methods()->length() + new_methods->length();
|
||||
int new_methods_length = klass->methods()->length() + new_methods->length();
|
||||
if (new_methods_length > USHRT_MAX) {
|
||||
THROW_MSG(vmSymbols::java_lang_InternalError(),
|
||||
"error methods for default method processing created too many methods");
|
||||
}
|
||||
u2 new_size = static_cast<u2>(new_methods_length);
|
||||
|
||||
Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>(
|
||||
klass->class_loader_data(), new_size, nullptr, CHECK);
|
||||
@ -1091,7 +1081,7 @@ static void merge_in_new_methods(InstanceKlass* klass,
|
||||
int orig_idx = 0;
|
||||
int new_idx = 0;
|
||||
|
||||
for (int i = 0; i < new_size; ++i) {
|
||||
for (u2 i = 0; i < new_size; ++i) {
|
||||
Method* orig_method = nullptr;
|
||||
Method* new_method = nullptr;
|
||||
if (orig_idx < original_methods->length()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user