1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/classfile/defaultMethods.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,1120 @@ 1.4 +/* 1.5 + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/bytecodeAssembler.hpp" 1.30 +#include "classfile/defaultMethods.hpp" 1.31 +#include "classfile/symbolTable.hpp" 1.32 +#include "memory/allocation.hpp" 1.33 +#include "memory/metadataFactory.hpp" 1.34 +#include "memory/resourceArea.hpp" 1.35 +#include "runtime/signature.hpp" 1.36 +#include "runtime/thread.hpp" 1.37 +#include "oops/instanceKlass.hpp" 1.38 +#include "oops/klass.hpp" 1.39 +#include "oops/method.hpp" 1.40 +#include "utilities/accessFlags.hpp" 1.41 +#include "utilities/exceptions.hpp" 1.42 +#include "utilities/ostream.hpp" 1.43 +#include "utilities/pair.hpp" 1.44 +#include "utilities/resourceHash.hpp" 1.45 + 1.46 +typedef enum { QUALIFIED, DISQUALIFIED } QualifiedState; 1.47 + 1.48 +// Because we use an iterative algorithm when iterating over the type 1.49 +// hierarchy, we can't use traditional scoped objects which automatically do 1.50 +// cleanup in the destructor when the scope is exited. PseudoScope (and 1.51 +// PseudoScopeMark) provides a similar functionality, but for when you want a 1.52 +// scoped object in non-stack memory (such as in resource memory, as we do 1.53 +// here). You've just got to remember to call 'destroy()' on the scope when 1.54 +// leaving it (and marks have to be explicitly added). 1.55 +class PseudoScopeMark : public ResourceObj { 1.56 + public: 1.57 + virtual void destroy() = 0; 1.58 +}; 1.59 + 1.60 +class PseudoScope : public ResourceObj { 1.61 + private: 1.62 + GrowableArray<PseudoScopeMark*> _marks; 1.63 + public: 1.64 + 1.65 + static PseudoScope* cast(void* data) { 1.66 + return static_cast<PseudoScope*>(data); 1.67 + } 1.68 + 1.69 + void add_mark(PseudoScopeMark* psm) { 1.70 + _marks.append(psm); 1.71 + } 1.72 + 1.73 + void destroy() { 1.74 + for (int i = 0; i < _marks.length(); ++i) { 1.75 + _marks.at(i)->destroy(); 1.76 + } 1.77 + } 1.78 +}; 1.79 + 1.80 +#ifndef PRODUCT 1.81 +static void print_slot(outputStream* str, Symbol* name, Symbol* signature) { 1.82 + ResourceMark rm; 1.83 + str->print("%s%s", name->as_C_string(), signature->as_C_string()); 1.84 +} 1.85 + 1.86 +static void print_method(outputStream* str, Method* mo, bool with_class=true) { 1.87 + ResourceMark rm; 1.88 + if (with_class) { 1.89 + str->print("%s.", mo->klass_name()->as_C_string()); 1.90 + } 1.91 + print_slot(str, mo->name(), mo->signature()); 1.92 +} 1.93 +#endif // ndef PRODUCT 1.94 + 1.95 +/** 1.96 + * Perform a depth-first iteration over the class hierarchy, applying 1.97 + * algorithmic logic as it goes. 1.98 + * 1.99 + * This class is one half of the inheritance hierarchy analysis mechanism. 1.100 + * It is meant to be used in conjunction with another class, the algorithm, 1.101 + * which is indicated by the ALGO template parameter. This class can be 1.102 + * paired with any algorithm class that provides the required methods. 1.103 + * 1.104 + * This class contains all the mechanics for iterating over the class hierarchy 1.105 + * starting at a particular root, without recursing (thus limiting stack growth 1.106 + * from this point). It visits each superclass (if present) and superinterface 1.107 + * in a depth-first manner, with callbacks to the ALGO class as each class is 1.108 + * encountered (visit()), The algorithm can cut-off further exploration of a 1.109 + * particular branch by returning 'false' from a visit() call. 1.110 + * 1.111 + * The ALGO class, must provide a visit() method, which each of which will be 1.112 + * called once for each node in the inheritance tree during the iteration. In 1.113 + * addition, it can provide a memory block via new_node_data(InstanceKlass*), 1.114 + * which it can use for node-specific storage (and access via the 1.115 + * current_data() and data_at_depth(int) methods). 1.116 + * 1.117 + * Bare minimum needed to be an ALGO class: 1.118 + * class Algo : public HierarchyVisitor<Algo> { 1.119 + * void* new_node_data(InstanceKlass* cls) { return NULL; } 1.120 + * void free_node_data(void* data) { return; } 1.121 + * bool visit() { return true; } 1.122 + * }; 1.123 + */ 1.124 +template <class ALGO> 1.125 +class HierarchyVisitor : StackObj { 1.126 + private: 1.127 + 1.128 + class Node : public ResourceObj { 1.129 + public: 1.130 + InstanceKlass* _class; 1.131 + bool _super_was_visited; 1.132 + int _interface_index; 1.133 + void* _algorithm_data; 1.134 + 1.135 + Node(InstanceKlass* cls, void* data, bool visit_super) 1.136 + : _class(cls), _super_was_visited(!visit_super), 1.137 + _interface_index(0), _algorithm_data(data) {} 1.138 + 1.139 + int number_of_interfaces() { return _class->local_interfaces()->length(); } 1.140 + int interface_index() { return _interface_index; } 1.141 + void set_super_visited() { _super_was_visited = true; } 1.142 + void increment_visited_interface() { ++_interface_index; } 1.143 + void set_all_interfaces_visited() { 1.144 + _interface_index = number_of_interfaces(); 1.145 + } 1.146 + bool has_visited_super() { return _super_was_visited; } 1.147 + bool has_visited_all_interfaces() { 1.148 + return interface_index() >= number_of_interfaces(); 1.149 + } 1.150 + InstanceKlass* interface_at(int index) { 1.151 + return InstanceKlass::cast(_class->local_interfaces()->at(index)); 1.152 + } 1.153 + InstanceKlass* next_super() { return _class->java_super(); } 1.154 + InstanceKlass* next_interface() { 1.155 + return interface_at(interface_index()); 1.156 + } 1.157 + }; 1.158 + 1.159 + bool _cancelled; 1.160 + GrowableArray<Node*> _path; 1.161 + 1.162 + Node* current_top() const { return _path.top(); } 1.163 + bool has_more_nodes() const { return !_path.is_empty(); } 1.164 + void push(InstanceKlass* cls, void* data) { 1.165 + assert(cls != NULL, "Requires a valid instance class"); 1.166 + Node* node = new Node(cls, data, has_super(cls)); 1.167 + _path.push(node); 1.168 + } 1.169 + void pop() { _path.pop(); } 1.170 + 1.171 + void reset_iteration() { 1.172 + _cancelled = false; 1.173 + _path.clear(); 1.174 + } 1.175 + bool is_cancelled() const { return _cancelled; } 1.176 + 1.177 + // This code used to skip interface classes because their only 1.178 + // superclass was j.l.Object which would be also covered by class 1.179 + // superclass hierarchy walks. Now that the starting point can be 1.180 + // an interface, we must ensure we catch j.l.Object as the super. 1.181 + static bool has_super(InstanceKlass* cls) { 1.182 + return cls->super() != NULL; 1.183 + } 1.184 + 1.185 + Node* node_at_depth(int i) const { 1.186 + return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1); 1.187 + } 1.188 + 1.189 + protected: 1.190 + 1.191 + // Accessors available to the algorithm 1.192 + int current_depth() const { return _path.length() - 1; } 1.193 + 1.194 + InstanceKlass* class_at_depth(int i) { 1.195 + Node* n = node_at_depth(i); 1.196 + return n == NULL ? NULL : n->_class; 1.197 + } 1.198 + InstanceKlass* current_class() { return class_at_depth(0); } 1.199 + 1.200 + void* data_at_depth(int i) { 1.201 + Node* n = node_at_depth(i); 1.202 + return n == NULL ? NULL : n->_algorithm_data; 1.203 + } 1.204 + void* current_data() { return data_at_depth(0); } 1.205 + 1.206 + void cancel_iteration() { _cancelled = true; } 1.207 + 1.208 + public: 1.209 + 1.210 + void run(InstanceKlass* root) { 1.211 + ALGO* algo = static_cast<ALGO*>(this); 1.212 + 1.213 + reset_iteration(); 1.214 + 1.215 + void* algo_data = algo->new_node_data(root); 1.216 + push(root, algo_data); 1.217 + bool top_needs_visit = true; 1.218 + 1.219 + do { 1.220 + Node* top = current_top(); 1.221 + if (top_needs_visit) { 1.222 + if (algo->visit() == false) { 1.223 + // algorithm does not want to continue along this path. Arrange 1.224 + // it so that this state is immediately popped off the stack 1.225 + top->set_super_visited(); 1.226 + top->set_all_interfaces_visited(); 1.227 + } 1.228 + top_needs_visit = false; 1.229 + } 1.230 + 1.231 + if (top->has_visited_super() && top->has_visited_all_interfaces()) { 1.232 + algo->free_node_data(top->_algorithm_data); 1.233 + pop(); 1.234 + } else { 1.235 + InstanceKlass* next = NULL; 1.236 + if (top->has_visited_super() == false) { 1.237 + next = top->next_super(); 1.238 + top->set_super_visited(); 1.239 + } else { 1.240 + next = top->next_interface(); 1.241 + top->increment_visited_interface(); 1.242 + } 1.243 + assert(next != NULL, "Otherwise we shouldn't be here"); 1.244 + algo_data = algo->new_node_data(next); 1.245 + push(next, algo_data); 1.246 + top_needs_visit = true; 1.247 + } 1.248 + } while (!is_cancelled() && has_more_nodes()); 1.249 + } 1.250 +}; 1.251 + 1.252 +#ifndef PRODUCT 1.253 +class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> { 1.254 + public: 1.255 + 1.256 + bool visit() { 1.257 + InstanceKlass* cls = current_class(); 1.258 + streamIndentor si(tty, current_depth() * 2); 1.259 + tty->indent().print_cr("%s", cls->name()->as_C_string()); 1.260 + return true; 1.261 + } 1.262 + 1.263 + void* new_node_data(InstanceKlass* cls) { return NULL; } 1.264 + void free_node_data(void* data) { return; } 1.265 +}; 1.266 +#endif // ndef PRODUCT 1.267 + 1.268 +// Used to register InstanceKlass objects and all related metadata structures 1.269 +// (Methods, ConstantPools) as "in-use" by the current thread so that they can't 1.270 +// be deallocated by class redefinition while we're using them. The classes are 1.271 +// de-registered when this goes out of scope. 1.272 +// 1.273 +// Once a class is registered, we need not bother with methodHandles or 1.274 +// constantPoolHandles for it's associated metadata. 1.275 +class KeepAliveRegistrar : public StackObj { 1.276 + private: 1.277 + Thread* _thread; 1.278 + GrowableArray<ConstantPool*> _keep_alive; 1.279 + 1.280 + public: 1.281 + KeepAliveRegistrar(Thread* thread) : _thread(thread), _keep_alive(20) { 1.282 + assert(thread == Thread::current(), "Must be current thread"); 1.283 + } 1.284 + 1.285 + ~KeepAliveRegistrar() { 1.286 + for (int i = _keep_alive.length() - 1; i >= 0; --i) { 1.287 + ConstantPool* cp = _keep_alive.at(i); 1.288 + int idx = _thread->metadata_handles()->find_from_end(cp); 1.289 + assert(idx > 0, "Must be in the list"); 1.290 + _thread->metadata_handles()->remove_at(idx); 1.291 + } 1.292 + } 1.293 + 1.294 + // Register a class as 'in-use' by the thread. It's fine to register a class 1.295 + // multiple times (though perhaps inefficient) 1.296 + void register_class(InstanceKlass* ik) { 1.297 + ConstantPool* cp = ik->constants(); 1.298 + _keep_alive.push(cp); 1.299 + _thread->metadata_handles()->push(cp); 1.300 + } 1.301 +}; 1.302 + 1.303 +class KeepAliveVisitor : public HierarchyVisitor<KeepAliveVisitor> { 1.304 + private: 1.305 + KeepAliveRegistrar* _registrar; 1.306 + 1.307 + public: 1.308 + KeepAliveVisitor(KeepAliveRegistrar* registrar) : _registrar(registrar) {} 1.309 + 1.310 + void* new_node_data(InstanceKlass* cls) { return NULL; } 1.311 + void free_node_data(void* data) { return; } 1.312 + 1.313 + bool visit() { 1.314 + _registrar->register_class(current_class()); 1.315 + return true; 1.316 + } 1.317 +}; 1.318 + 1.319 + 1.320 +// A method family contains a set of all methods that implement a single 1.321 +// erased method. As members of the set are collected while walking over the 1.322 +// hierarchy, they are tagged with a qualification state. The qualification 1.323 +// state for an erased method is set to disqualified if there exists a path 1.324 +// from the root of hierarchy to the method that contains an interleaving 1.325 +// erased method defined in an interface. 1.326 + 1.327 +class MethodFamily : public ResourceObj { 1.328 + private: 1.329 + 1.330 + GrowableArray<Pair<Method*,QualifiedState> > _members; 1.331 + ResourceHashtable<Method*, int> _member_index; 1.332 + 1.333 + Method* _selected_target; // Filled in later, if a unique target exists 1.334 + Symbol* _exception_message; // If no unique target is found 1.335 + Symbol* _exception_name; // If no unique target is found 1.336 + 1.337 + bool contains_method(Method* method) { 1.338 + int* lookup = _member_index.get(method); 1.339 + return lookup != NULL; 1.340 + } 1.341 + 1.342 + void add_method(Method* method, QualifiedState state) { 1.343 + Pair<Method*,QualifiedState> entry(method, state); 1.344 + _member_index.put(method, _members.length()); 1.345 + _members.append(entry); 1.346 + } 1.347 + 1.348 + void disqualify_method(Method* method) { 1.349 + int* index = _member_index.get(method); 1.350 + guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index"); 1.351 + _members.at(*index).second = DISQUALIFIED; 1.352 + } 1.353 + 1.354 + Symbol* generate_no_defaults_message(TRAPS) const; 1.355 + Symbol* generate_method_message(Symbol *klass_name, Method* method, TRAPS) const; 1.356 + Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const; 1.357 + 1.358 + public: 1.359 + 1.360 + MethodFamily() 1.361 + : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {} 1.362 + 1.363 + void set_target_if_empty(Method* m) { 1.364 + if (_selected_target == NULL && !m->is_overpass()) { 1.365 + _selected_target = m; 1.366 + } 1.367 + } 1.368 + 1.369 + void record_qualified_method(Method* m) { 1.370 + // If the method already exists in the set as qualified, this operation is 1.371 + // redundant. If it already exists as disqualified, then we leave it as 1.372 + // disqualfied. Thus we only add to the set if it's not already in the 1.373 + // set. 1.374 + if (!contains_method(m)) { 1.375 + add_method(m, QUALIFIED); 1.376 + } 1.377 + } 1.378 + 1.379 + void record_disqualified_method(Method* m) { 1.380 + // If not in the set, add it as disqualified. If it's already in the set, 1.381 + // then set the state to disqualified no matter what the previous state was. 1.382 + if (!contains_method(m)) { 1.383 + add_method(m, DISQUALIFIED); 1.384 + } else { 1.385 + disqualify_method(m); 1.386 + } 1.387 + } 1.388 + 1.389 + bool has_target() const { return _selected_target != NULL; } 1.390 + bool throws_exception() { return _exception_message != NULL; } 1.391 + 1.392 + Method* get_selected_target() { return _selected_target; } 1.393 + Symbol* get_exception_message() { return _exception_message; } 1.394 + Symbol* get_exception_name() { return _exception_name; } 1.395 + 1.396 + // Either sets the target or the exception error message 1.397 + void determine_target(InstanceKlass* root, TRAPS) { 1.398 + if (has_target() || throws_exception()) { 1.399 + return; 1.400 + } 1.401 + 1.402 + // Qualified methods are maximally-specific methods 1.403 + // These include public, instance concrete (=default) and abstract methods 1.404 + GrowableArray<Method*> qualified_methods; 1.405 + int num_defaults = 0; 1.406 + int default_index = -1; 1.407 + int qualified_index = -1; 1.408 + for (int i = 0; i < _members.length(); ++i) { 1.409 + Pair<Method*,QualifiedState> entry = _members.at(i); 1.410 + if (entry.second == QUALIFIED) { 1.411 + qualified_methods.append(entry.first); 1.412 + qualified_index++; 1.413 + if (entry.first->is_default_method()) { 1.414 + num_defaults++; 1.415 + default_index = qualified_index; 1.416 + 1.417 + } 1.418 + } 1.419 + } 1.420 + 1.421 + if (num_defaults == 0) { 1.422 + // If the root klass has a static method with matching name and signature 1.423 + // then do not generate an overpass method because it will hide the 1.424 + // static method during resolution. 1.425 + if (qualified_methods.length() == 0) { 1.426 + _exception_message = generate_no_defaults_message(CHECK); 1.427 + } else { 1.428 + assert(root != NULL, "Null root class"); 1.429 + _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK); 1.430 + } 1.431 + _exception_name = vmSymbols::java_lang_AbstractMethodError(); 1.432 + 1.433 + // If only one qualified method is default, select that 1.434 + } else if (num_defaults == 1) { 1.435 + _selected_target = qualified_methods.at(default_index); 1.436 + 1.437 + } else if (num_defaults > 1) { 1.438 + _exception_message = generate_conflicts_message(&qualified_methods,CHECK); 1.439 + _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); 1.440 + if (TraceDefaultMethods) { 1.441 + _exception_message->print_value_on(tty); 1.442 + tty->cr(); 1.443 + } 1.444 + } 1.445 + } 1.446 + 1.447 + bool contains_signature(Symbol* query) { 1.448 + for (int i = 0; i < _members.length(); ++i) { 1.449 + if (query == _members.at(i).first->signature()) { 1.450 + return true; 1.451 + } 1.452 + } 1.453 + return false; 1.454 + } 1.455 + 1.456 +#ifndef PRODUCT 1.457 + void print_sig_on(outputStream* str, Symbol* signature, int indent) const { 1.458 + streamIndentor si(str, indent * 2); 1.459 + 1.460 + str->indent().print_cr("Logical Method %s:", signature->as_C_string()); 1.461 + 1.462 + streamIndentor si2(str); 1.463 + for (int i = 0; i < _members.length(); ++i) { 1.464 + str->indent(); 1.465 + print_method(str, _members.at(i).first); 1.466 + if (_members.at(i).second == DISQUALIFIED) { 1.467 + str->print(" (disqualified)"); 1.468 + } 1.469 + str->cr(); 1.470 + } 1.471 + 1.472 + if (_selected_target != NULL) { 1.473 + print_selected(str, 1); 1.474 + } 1.475 + } 1.476 + 1.477 + void print_selected(outputStream* str, int indent) const { 1.478 + assert(has_target(), "Should be called otherwise"); 1.479 + streamIndentor si(str, indent * 2); 1.480 + str->indent().print("Selected method: "); 1.481 + print_method(str, _selected_target); 1.482 + Klass* method_holder = _selected_target->method_holder(); 1.483 + if (!method_holder->is_interface()) { 1.484 + tty->print(" : in superclass"); 1.485 + } 1.486 + str->cr(); 1.487 + } 1.488 + 1.489 + void print_exception(outputStream* str, int indent) { 1.490 + assert(throws_exception(), "Should be called otherwise"); 1.491 + assert(_exception_name != NULL, "exception_name should be set"); 1.492 + streamIndentor si(str, indent * 2); 1.493 + str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string()); 1.494 + } 1.495 +#endif // ndef PRODUCT 1.496 +}; 1.497 + 1.498 +Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { 1.499 + return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL); 1.500 +} 1.501 + 1.502 +Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method, TRAPS) const { 1.503 + stringStream ss; 1.504 + ss.print("Method "); 1.505 + Symbol* name = method->name(); 1.506 + Symbol* signature = method->signature(); 1.507 + ss.write((const char*)klass_name->bytes(), klass_name->utf8_length()); 1.508 + ss.print("."); 1.509 + ss.write((const char*)name->bytes(), name->utf8_length()); 1.510 + ss.write((const char*)signature->bytes(), signature->utf8_length()); 1.511 + ss.print(" is abstract"); 1.512 + return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); 1.513 +} 1.514 + 1.515 +Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const { 1.516 + stringStream ss; 1.517 + ss.print("Conflicting default methods:"); 1.518 + for (int i = 0; i < methods->length(); ++i) { 1.519 + Method* method = methods->at(i); 1.520 + Symbol* klass = method->klass_name(); 1.521 + Symbol* name = method->name(); 1.522 + ss.print(" "); 1.523 + ss.write((const char*)klass->bytes(), klass->utf8_length()); 1.524 + ss.print("."); 1.525 + ss.write((const char*)name->bytes(), name->utf8_length()); 1.526 + } 1.527 + return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); 1.528 +} 1.529 + 1.530 + 1.531 +class StateRestorer; 1.532 + 1.533 +// StatefulMethodFamily is a wrapper around a MethodFamily that maintains the 1.534 +// qualification state during hierarchy visitation, and applies that state 1.535 +// when adding members to the MethodFamily 1.536 +class StatefulMethodFamily : public ResourceObj { 1.537 + friend class StateRestorer; 1.538 + private: 1.539 + QualifiedState _qualification_state; 1.540 + 1.541 + void set_qualification_state(QualifiedState state) { 1.542 + _qualification_state = state; 1.543 + } 1.544 + 1.545 + protected: 1.546 + MethodFamily* _method_family; 1.547 + 1.548 + public: 1.549 + StatefulMethodFamily() { 1.550 + _method_family = new MethodFamily(); 1.551 + _qualification_state = QUALIFIED; 1.552 + } 1.553 + 1.554 + StatefulMethodFamily(MethodFamily* mf) { 1.555 + _method_family = mf; 1.556 + _qualification_state = QUALIFIED; 1.557 + } 1.558 + 1.559 + void set_target_if_empty(Method* m) { _method_family->set_target_if_empty(m); } 1.560 + 1.561 + MethodFamily* get_method_family() { return _method_family; } 1.562 + 1.563 + StateRestorer* record_method_and_dq_further(Method* mo); 1.564 +}; 1.565 + 1.566 +class StateRestorer : public PseudoScopeMark { 1.567 + private: 1.568 + StatefulMethodFamily* _method; 1.569 + QualifiedState _state_to_restore; 1.570 + public: 1.571 + StateRestorer(StatefulMethodFamily* dm, QualifiedState state) 1.572 + : _method(dm), _state_to_restore(state) {} 1.573 + ~StateRestorer() { destroy(); } 1.574 + void restore_state() { _method->set_qualification_state(_state_to_restore); } 1.575 + virtual void destroy() { restore_state(); } 1.576 +}; 1.577 + 1.578 +StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) { 1.579 + StateRestorer* mark = new StateRestorer(this, _qualification_state); 1.580 + if (_qualification_state == QUALIFIED) { 1.581 + _method_family->record_qualified_method(mo); 1.582 + } else { 1.583 + _method_family->record_disqualified_method(mo); 1.584 + } 1.585 + // Everything found "above"??? this method in the hierarchy walk is set to 1.586 + // disqualified 1.587 + set_qualification_state(DISQUALIFIED); 1.588 + return mark; 1.589 +} 1.590 + 1.591 +// Represents a location corresponding to a vtable slot for methods that 1.592 +// neither the class nor any of it's ancestors provide an implementaion. 1.593 +// Default methods may be present to fill this slot. 1.594 +class EmptyVtableSlot : public ResourceObj { 1.595 + private: 1.596 + Symbol* _name; 1.597 + Symbol* _signature; 1.598 + int _size_of_parameters; 1.599 + MethodFamily* _binding; 1.600 + 1.601 + public: 1.602 + EmptyVtableSlot(Method* method) 1.603 + : _name(method->name()), _signature(method->signature()), 1.604 + _size_of_parameters(method->size_of_parameters()), _binding(NULL) {} 1.605 + 1.606 + Symbol* name() const { return _name; } 1.607 + Symbol* signature() const { return _signature; } 1.608 + int size_of_parameters() const { return _size_of_parameters; } 1.609 + 1.610 + void bind_family(MethodFamily* lm) { _binding = lm; } 1.611 + bool is_bound() { return _binding != NULL; } 1.612 + MethodFamily* get_binding() { return _binding; } 1.613 + 1.614 +#ifndef PRODUCT 1.615 + void print_on(outputStream* str) const { 1.616 + print_slot(str, name(), signature()); 1.617 + } 1.618 +#endif // ndef PRODUCT 1.619 +}; 1.620 + 1.621 +static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) { 1.622 + bool found = false; 1.623 + for (int j = 0; j < slots->length(); ++j) { 1.624 + if (slots->at(j)->name() == m->name() && 1.625 + slots->at(j)->signature() == m->signature() ) { 1.626 + found = true; 1.627 + break; 1.628 + } 1.629 + } 1.630 + return found; 1.631 +} 1.632 + 1.633 +static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots( 1.634 + InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) { 1.635 + 1.636 + assert(klass != NULL, "Must be valid class"); 1.637 + 1.638 + GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>(); 1.639 + 1.640 + // All miranda methods are obvious candidates 1.641 + for (int i = 0; i < mirandas->length(); ++i) { 1.642 + Method* m = mirandas->at(i); 1.643 + if (!already_in_vtable_slots(slots, m)) { 1.644 + slots->append(new EmptyVtableSlot(m)); 1.645 + } 1.646 + } 1.647 + 1.648 + // Also any overpasses in our superclasses, that we haven't implemented. 1.649 + // (can't use the vtable because it is not guaranteed to be initialized yet) 1.650 + InstanceKlass* super = klass->java_super(); 1.651 + while (super != NULL) { 1.652 + for (int i = 0; i < super->methods()->length(); ++i) { 1.653 + Method* m = super->methods()->at(i); 1.654 + if (m->is_overpass() || m->is_static()) { 1.655 + // m is a method that would have been a miranda if not for the 1.656 + // default method processing that occurred on behalf of our superclass, 1.657 + // so it's a method we want to re-examine in this new context. That is, 1.658 + // unless we have a real implementation of it in the current class. 1.659 + Method* impl = klass->lookup_method(m->name(), m->signature()); 1.660 + if (impl == NULL || impl->is_overpass() || impl->is_static()) { 1.661 + if (!already_in_vtable_slots(slots, m)) { 1.662 + slots->append(new EmptyVtableSlot(m)); 1.663 + } 1.664 + } 1.665 + } 1.666 + } 1.667 + 1.668 + // also any default methods in our superclasses 1.669 + if (super->default_methods() != NULL) { 1.670 + for (int i = 0; i < super->default_methods()->length(); ++i) { 1.671 + Method* m = super->default_methods()->at(i); 1.672 + // m is a method that would have been a miranda if not for the 1.673 + // default method processing that occurred on behalf of our superclass, 1.674 + // so it's a method we want to re-examine in this new context. That is, 1.675 + // unless we have a real implementation of it in the current class. 1.676 + Method* impl = klass->lookup_method(m->name(), m->signature()); 1.677 + if (impl == NULL || impl->is_overpass() || impl->is_static()) { 1.678 + if (!already_in_vtable_slots(slots, m)) { 1.679 + slots->append(new EmptyVtableSlot(m)); 1.680 + } 1.681 + } 1.682 + } 1.683 + } 1.684 + super = super->java_super(); 1.685 + } 1.686 + 1.687 +#ifndef PRODUCT 1.688 + if (TraceDefaultMethods) { 1.689 + tty->print_cr("Slots that need filling:"); 1.690 + streamIndentor si(tty); 1.691 + for (int i = 0; i < slots->length(); ++i) { 1.692 + tty->indent(); 1.693 + slots->at(i)->print_on(tty); 1.694 + tty->cr(); 1.695 + } 1.696 + } 1.697 +#endif // ndef PRODUCT 1.698 + return slots; 1.699 +} 1.700 + 1.701 +// Iterates over the superinterface type hierarchy looking for all methods 1.702 +// with a specific erased signature. 1.703 +class FindMethodsByErasedSig : public HierarchyVisitor<FindMethodsByErasedSig> { 1.704 + private: 1.705 + // Context data 1.706 + Symbol* _method_name; 1.707 + Symbol* _method_signature; 1.708 + StatefulMethodFamily* _family; 1.709 + 1.710 + public: 1.711 + FindMethodsByErasedSig(Symbol* name, Symbol* signature) : 1.712 + _method_name(name), _method_signature(signature), 1.713 + _family(NULL) {} 1.714 + 1.715 + void get_discovered_family(MethodFamily** family) { 1.716 + if (_family != NULL) { 1.717 + *family = _family->get_method_family(); 1.718 + } else { 1.719 + *family = NULL; 1.720 + } 1.721 + } 1.722 + 1.723 + void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); } 1.724 + void free_node_data(void* node_data) { 1.725 + PseudoScope::cast(node_data)->destroy(); 1.726 + } 1.727 + 1.728 + // Find all methods on this hierarchy that match this 1.729 + // method's erased (name, signature) 1.730 + bool visit() { 1.731 + PseudoScope* scope = PseudoScope::cast(current_data()); 1.732 + InstanceKlass* iklass = current_class(); 1.733 + 1.734 + Method* m = iklass->find_method(_method_name, _method_signature); 1.735 + // private interface methods are not candidates for default methods 1.736 + // invokespecial to private interface methods doesn't use default method logic 1.737 + // The overpasses are your supertypes' errors, we do not include them 1.738 + // future: take access controls into account for superclass methods 1.739 + if (m != NULL && !m->is_static() && !m->is_overpass() && 1.740 + (!iklass->is_interface() || m->is_public())) { 1.741 + if (_family == NULL) { 1.742 + _family = new StatefulMethodFamily(); 1.743 + } 1.744 + 1.745 + if (iklass->is_interface()) { 1.746 + StateRestorer* restorer = _family->record_method_and_dq_further(m); 1.747 + scope->add_mark(restorer); 1.748 + } else { 1.749 + // This is the rule that methods in classes "win" (bad word) over 1.750 + // methods in interfaces. This works because of single inheritance 1.751 + _family->set_target_if_empty(m); 1.752 + } 1.753 + } 1.754 + return true; 1.755 + } 1.756 + 1.757 +}; 1.758 + 1.759 + 1.760 + 1.761 +static void create_defaults_and_exceptions( 1.762 + GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS); 1.763 + 1.764 +static void generate_erased_defaults( 1.765 + InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots, 1.766 + EmptyVtableSlot* slot, TRAPS) { 1.767 + 1.768 + // sets up a set of methods with the same exact erased signature 1.769 + FindMethodsByErasedSig visitor(slot->name(), slot->signature()); 1.770 + visitor.run(klass); 1.771 + 1.772 + MethodFamily* family; 1.773 + visitor.get_discovered_family(&family); 1.774 + if (family != NULL) { 1.775 + family->determine_target(klass, CHECK); 1.776 + slot->bind_family(family); 1.777 + } 1.778 +} 1.779 + 1.780 +static void merge_in_new_methods(InstanceKlass* klass, 1.781 + GrowableArray<Method*>* new_methods, TRAPS); 1.782 +static void create_default_methods( InstanceKlass* klass, 1.783 + GrowableArray<Method*>* new_methods, TRAPS); 1.784 + 1.785 +// This is the guts of the default methods implementation. This is called just 1.786 +// after the classfile has been parsed if some ancestor has default methods. 1.787 +// 1.788 +// First if finds any name/signature slots that need any implementation (either 1.789 +// because they are miranda or a superclass's implementation is an overpass 1.790 +// itself). For each slot, iterate over the hierarchy, to see if they contain a 1.791 +// signature that matches the slot we are looking at. 1.792 +// 1.793 +// For each slot filled, we generate an overpass method that either calls the 1.794 +// unique default method candidate using invokespecial, or throws an exception 1.795 +// (in the case of no default method candidates, or more than one valid 1.796 +// candidate). These methods are then added to the class's method list. 1.797 +// The JVM does not create bridges nor handle generic signatures here. 1.798 +void DefaultMethods::generate_default_methods( 1.799 + InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) { 1.800 + 1.801 + // This resource mark is the bound for all memory allocation that takes 1.802 + // place during default method processing. After this goes out of scope, 1.803 + // all (Resource) objects' memory will be reclaimed. Be careful if adding an 1.804 + // embedded resource mark under here as that memory can't be used outside 1.805 + // whatever scope it's in. 1.806 + ResourceMark rm(THREAD); 1.807 + 1.808 + // Keep entire hierarchy alive for the duration of the computation 1.809 + KeepAliveRegistrar keepAlive(THREAD); 1.810 + KeepAliveVisitor loadKeepAlive(&keepAlive); 1.811 + loadKeepAlive.run(klass); 1.812 + 1.813 +#ifndef PRODUCT 1.814 + if (TraceDefaultMethods) { 1.815 + ResourceMark rm; // be careful with these! 1.816 + tty->print_cr("%s %s requires default method processing", 1.817 + klass->is_interface() ? "Interface" : "Class", 1.818 + klass->name()->as_klass_external_name()); 1.819 + PrintHierarchy printer; 1.820 + printer.run(klass); 1.821 + } 1.822 +#endif // ndef PRODUCT 1.823 + 1.824 + GrowableArray<EmptyVtableSlot*>* empty_slots = 1.825 + find_empty_vtable_slots(klass, mirandas, CHECK); 1.826 + 1.827 + for (int i = 0; i < empty_slots->length(); ++i) { 1.828 + EmptyVtableSlot* slot = empty_slots->at(i); 1.829 +#ifndef PRODUCT 1.830 + if (TraceDefaultMethods) { 1.831 + streamIndentor si(tty, 2); 1.832 + tty->indent().print("Looking for default methods for slot "); 1.833 + slot->print_on(tty); 1.834 + tty->cr(); 1.835 + } 1.836 +#endif // ndef PRODUCT 1.837 + 1.838 + generate_erased_defaults(klass, empty_slots, slot, CHECK); 1.839 + } 1.840 +#ifndef PRODUCT 1.841 + if (TraceDefaultMethods) { 1.842 + tty->print_cr("Creating defaults and overpasses..."); 1.843 + } 1.844 +#endif // ndef PRODUCT 1.845 + 1.846 + create_defaults_and_exceptions(empty_slots, klass, CHECK); 1.847 + 1.848 +#ifndef PRODUCT 1.849 + if (TraceDefaultMethods) { 1.850 + tty->print_cr("Default method processing complete"); 1.851 + } 1.852 +#endif // ndef PRODUCT 1.853 +} 1.854 + 1.855 +static int assemble_method_error( 1.856 + BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { 1.857 + 1.858 + Symbol* init = vmSymbols::object_initializer_name(); 1.859 + Symbol* sig = vmSymbols::string_void_signature(); 1.860 + 1.861 + BytecodeAssembler assem(buffer, cp); 1.862 + 1.863 + assem._new(errorName); 1.864 + assem.dup(); 1.865 + assem.load_string(message); 1.866 + assem.invokespecial(errorName, init, sig); 1.867 + assem.athrow(); 1.868 + 1.869 + return 3; // max stack size: [ exception, exception, string ] 1.870 +} 1.871 + 1.872 +static Method* new_method( 1.873 + BytecodeConstantPool* cp, BytecodeBuffer* bytecodes, Symbol* name, 1.874 + Symbol* sig, AccessFlags flags, int max_stack, int params, 1.875 + ConstMethod::MethodType mt, TRAPS) { 1.876 + 1.877 + address code_start = 0; 1.878 + int code_length = 0; 1.879 + InlineTableSizes sizes; 1.880 + 1.881 + if (bytecodes != NULL && bytecodes->length() > 0) { 1.882 + code_start = static_cast<address>(bytecodes->adr_at(0)); 1.883 + code_length = bytecodes->length(); 1.884 + } 1.885 + 1.886 + Method* m = Method::allocate(cp->pool_holder()->class_loader_data(), 1.887 + code_length, flags, &sizes, 1.888 + mt, CHECK_NULL); 1.889 + 1.890 + m->set_constants(NULL); // This will get filled in later 1.891 + m->set_name_index(cp->utf8(name)); 1.892 + m->set_signature_index(cp->utf8(sig)); 1.893 +#ifdef CC_INTERP 1.894 + ResultTypeFinder rtf(sig); 1.895 + m->set_result_index(rtf.type()); 1.896 +#endif 1.897 + m->set_size_of_parameters(params); 1.898 + m->set_max_stack(max_stack); 1.899 + m->set_max_locals(params); 1.900 + m->constMethod()->set_stackmap_data(NULL); 1.901 + m->set_code(code_start); 1.902 + 1.903 + return m; 1.904 +} 1.905 + 1.906 +static void switchover_constant_pool(BytecodeConstantPool* bpool, 1.907 + InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPS) { 1.908 + 1.909 + if (new_methods->length() > 0) { 1.910 + ConstantPool* cp = bpool->create_constant_pool(CHECK); 1.911 + if (cp != klass->constants()) { 1.912 + klass->class_loader_data()->add_to_deallocate_list(klass->constants()); 1.913 + klass->set_constants(cp); 1.914 + cp->set_pool_holder(klass); 1.915 + 1.916 + for (int i = 0; i < new_methods->length(); ++i) { 1.917 + new_methods->at(i)->set_constants(cp); 1.918 + } 1.919 + for (int i = 0; i < klass->methods()->length(); ++i) { 1.920 + Method* mo = klass->methods()->at(i); 1.921 + mo->set_constants(cp); 1.922 + } 1.923 + } 1.924 + } 1.925 +} 1.926 + 1.927 +// Create default_methods list for the current class. 1.928 +// With the VM only processing erased signatures, the VM only 1.929 +// creates an overpass in a conflict case or a case with no candidates. 1.930 +// This allows virtual methods to override the overpass, but ensures 1.931 +// that a local method search will find the exception rather than an abstract 1.932 +// or default method that is not a valid candidate. 1.933 +static void create_defaults_and_exceptions( 1.934 + GrowableArray<EmptyVtableSlot*>* slots, 1.935 + InstanceKlass* klass, TRAPS) { 1.936 + 1.937 + GrowableArray<Method*> overpasses; 1.938 + GrowableArray<Method*> defaults; 1.939 + BytecodeConstantPool bpool(klass->constants()); 1.940 + 1.941 + for (int i = 0; i < slots->length(); ++i) { 1.942 + EmptyVtableSlot* slot = slots->at(i); 1.943 + 1.944 + if (slot->is_bound()) { 1.945 + MethodFamily* method = slot->get_binding(); 1.946 + BytecodeBuffer buffer; 1.947 + 1.948 +#ifndef PRODUCT 1.949 + if (TraceDefaultMethods) { 1.950 + tty->print("for slot: "); 1.951 + slot->print_on(tty); 1.952 + tty->cr(); 1.953 + if (method->has_target()) { 1.954 + method->print_selected(tty, 1); 1.955 + } else if (method->throws_exception()) { 1.956 + method->print_exception(tty, 1); 1.957 + } 1.958 + } 1.959 +#endif // ndef PRODUCT 1.960 + 1.961 + if (method->has_target()) { 1.962 + Method* selected = method->get_selected_target(); 1.963 + if (selected->method_holder()->is_interface()) { 1.964 + defaults.push(selected); 1.965 + } 1.966 + } else if (method->throws_exception()) { 1.967 + int max_stack = assemble_method_error(&bpool, &buffer, 1.968 + method->get_exception_name(), method->get_exception_message(), CHECK); 1.969 + AccessFlags flags = accessFlags_from( 1.970 + JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); 1.971 + Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), 1.972 + flags, max_stack, slot->size_of_parameters(), 1.973 + ConstMethod::OVERPASS, CHECK); 1.974 + // We push to the methods list: 1.975 + // overpass methods which are exception throwing methods 1.976 + if (m != NULL) { 1.977 + overpasses.push(m); 1.978 + } 1.979 + } 1.980 + } 1.981 + } 1.982 + 1.983 +#ifndef PRODUCT 1.984 + if (TraceDefaultMethods) { 1.985 + tty->print_cr("Created %d overpass methods", overpasses.length()); 1.986 + tty->print_cr("Created %d default methods", defaults.length()); 1.987 + } 1.988 +#endif // ndef PRODUCT 1.989 + 1.990 + if (overpasses.length() > 0) { 1.991 + switchover_constant_pool(&bpool, klass, &overpasses, CHECK); 1.992 + merge_in_new_methods(klass, &overpasses, CHECK); 1.993 + } 1.994 + if (defaults.length() > 0) { 1.995 + create_default_methods(klass, &defaults, CHECK); 1.996 + } 1.997 +} 1.998 + 1.999 +static void create_default_methods( InstanceKlass* klass, 1.1000 + GrowableArray<Method*>* new_methods, TRAPS) { 1.1001 + 1.1002 + int new_size = new_methods->length(); 1.1003 + Array<Method*>* total_default_methods = MetadataFactory::new_array<Method*>( 1.1004 + klass->class_loader_data(), new_size, NULL, CHECK); 1.1005 + for (int index = 0; index < new_size; index++ ) { 1.1006 + total_default_methods->at_put(index, new_methods->at(index)); 1.1007 + } 1.1008 + Method::sort_methods(total_default_methods, false, false); 1.1009 + 1.1010 + klass->set_default_methods(total_default_methods); 1.1011 +} 1.1012 + 1.1013 +static void sort_methods(GrowableArray<Method*>* methods) { 1.1014 + // Note that this must sort using the same key as is used for sorting 1.1015 + // methods in InstanceKlass. 1.1016 + bool sorted = true; 1.1017 + for (int i = methods->length() - 1; i > 0; --i) { 1.1018 + for (int j = 0; j < i; ++j) { 1.1019 + Method* m1 = methods->at(j); 1.1020 + Method* m2 = methods->at(j + 1); 1.1021 + if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) { 1.1022 + methods->at_put(j, m2); 1.1023 + methods->at_put(j + 1, m1); 1.1024 + sorted = false; 1.1025 + } 1.1026 + } 1.1027 + if (sorted) break; 1.1028 + sorted = true; 1.1029 + } 1.1030 +#ifdef ASSERT 1.1031 + uintptr_t prev = 0; 1.1032 + for (int i = 0; i < methods->length(); ++i) { 1.1033 + Method* mh = methods->at(i); 1.1034 + uintptr_t nv = (uintptr_t)mh->name(); 1.1035 + assert(nv >= prev, "Incorrect overpass method ordering"); 1.1036 + prev = nv; 1.1037 + } 1.1038 +#endif 1.1039 +} 1.1040 + 1.1041 +static void merge_in_new_methods(InstanceKlass* klass, 1.1042 + GrowableArray<Method*>* new_methods, TRAPS) { 1.1043 + 1.1044 + enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS }; 1.1045 + 1.1046 + Array<Method*>* original_methods = klass->methods(); 1.1047 + Array<int>* original_ordering = klass->method_ordering(); 1.1048 + Array<int>* merged_ordering = Universe::the_empty_int_array(); 1.1049 + 1.1050 + int new_size = klass->methods()->length() + new_methods->length(); 1.1051 + 1.1052 + Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>( 1.1053 + klass->class_loader_data(), new_size, NULL, CHECK); 1.1054 + 1.1055 + // original_ordering might be empty if this class has no methods of its own 1.1056 + if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) { 1.1057 + merged_ordering = MetadataFactory::new_array<int>( 1.1058 + klass->class_loader_data(), new_size, CHECK); 1.1059 + } 1.1060 + int method_order_index = klass->methods()->length(); 1.1061 + 1.1062 + sort_methods(new_methods); 1.1063 + 1.1064 + // Perform grand merge of existing methods and new methods 1.1065 + int orig_idx = 0; 1.1066 + int new_idx = 0; 1.1067 + 1.1068 + for (int i = 0; i < new_size; ++i) { 1.1069 + Method* orig_method = NULL; 1.1070 + Method* new_method = NULL; 1.1071 + if (orig_idx < original_methods->length()) { 1.1072 + orig_method = original_methods->at(orig_idx); 1.1073 + } 1.1074 + if (new_idx < new_methods->length()) { 1.1075 + new_method = new_methods->at(new_idx); 1.1076 + } 1.1077 + 1.1078 + if (orig_method != NULL && 1.1079 + (new_method == NULL || orig_method->name() < new_method->name())) { 1.1080 + merged_methods->at_put(i, orig_method); 1.1081 + original_methods->at_put(orig_idx, NULL); 1.1082 + if (merged_ordering->length() > 0) { 1.1083 + assert(original_ordering != NULL && original_ordering->length() > 0, 1.1084 + "should have original order information for this method"); 1.1085 + merged_ordering->at_put(i, original_ordering->at(orig_idx)); 1.1086 + } 1.1087 + ++orig_idx; 1.1088 + } else { 1.1089 + merged_methods->at_put(i, new_method); 1.1090 + if (merged_ordering->length() > 0) { 1.1091 + merged_ordering->at_put(i, method_order_index++); 1.1092 + } 1.1093 + ++new_idx; 1.1094 + } 1.1095 + // update idnum for new location 1.1096 + merged_methods->at(i)->set_method_idnum(i); 1.1097 + } 1.1098 + 1.1099 + // Verify correct order 1.1100 +#ifdef ASSERT 1.1101 + uintptr_t prev = 0; 1.1102 + for (int i = 0; i < merged_methods->length(); ++i) { 1.1103 + Method* mo = merged_methods->at(i); 1.1104 + uintptr_t nv = (uintptr_t)mo->name(); 1.1105 + assert(nv >= prev, "Incorrect method ordering"); 1.1106 + prev = nv; 1.1107 + } 1.1108 +#endif 1.1109 + 1.1110 + // Replace klass methods with new merged lists 1.1111 + klass->set_methods(merged_methods); 1.1112 + klass->set_initial_method_idnum(new_size); 1.1113 + klass->set_method_ordering(merged_ordering); 1.1114 + 1.1115 + // Free metadata 1.1116 + ClassLoaderData* cld = klass->class_loader_data(); 1.1117 + if (original_methods->length() > 0) { 1.1118 + MetadataFactory::free_array(cld, original_methods); 1.1119 + } 1.1120 + if (original_ordering != NULL && original_ordering->length() > 0) { 1.1121 + MetadataFactory::free_array(cld, original_ordering); 1.1122 + } 1.1123 +}