Tue, 13 Dec 2016 14:37:04 -0500
8168699: Validate special case invocations
Reviewed-by: kevinw, vlivanov
1.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Mon Nov 21 22:56:59 2016 -0800 1.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Tue Dec 13 14:37:04 2016 -0500 1.3 @@ -1023,11 +1023,16 @@ 1.4 obj.load_item(); 1.5 LIR_Opr out_reg = rlock_result(x); 1.6 CodeStub* stub; 1.7 - CodeEmitInfo* info_for_exception = state_for(x); 1.8 + CodeEmitInfo* info_for_exception = 1.9 + (x->needs_exception_state() ? state_for(x) : 1.10 + state_for(x, x->state_before(), true /*ignore_xhandler*/)); 1.11 1.12 if (x->is_incompatible_class_change_check()) { 1.13 assert(patching_info == NULL, "can't patch this"); 1.14 stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); 1.15 + } else if (x->is_invokespecial_receiver_check()) { 1.16 + assert(patching_info == NULL, "can't patch this"); 1.17 + stub = new DeoptimizeStub(info_for_exception); 1.18 } else { 1.19 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); 1.20 }
2.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Nov 21 22:56:59 2016 -0800 2.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Tue Dec 13 14:37:04 2016 -0500 2.3 @@ -1228,12 +1228,17 @@ 2.4 obj.load_item(); 2.5 2.6 // info for exceptions 2.7 - CodeEmitInfo* info_for_exception = state_for(x); 2.8 + CodeEmitInfo* info_for_exception = 2.9 + (x->needs_exception_state() ? state_for(x) : 2.10 + state_for(x, x->state_before(), true /*ignore_xhandler*/)); 2.11 2.12 CodeStub* stub; 2.13 if (x->is_incompatible_class_change_check()) { 2.14 assert(patching_info == NULL, "can't patch this"); 2.15 stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); 2.16 + } else if (x->is_invokespecial_receiver_check()) { 2.17 + assert(patching_info == NULL, "can't patch this"); 2.18 + stub = new DeoptimizeStub(info_for_exception); 2.19 } else { 2.20 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); 2.21 }
3.1 --- a/src/share/vm/c1/c1_CodeStubs.hpp Mon Nov 21 22:56:59 2016 -0800 3.2 +++ b/src/share/vm/c1/c1_CodeStubs.hpp Tue Dec 13 14:37:04 2016 -0500 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -57,6 +57,7 @@ 3.11 virtual bool is_exception_throw_stub() const { return false; } 3.12 virtual bool is_range_check_stub() const { return false; } 3.13 virtual bool is_divbyzero_stub() const { return false; } 3.14 + virtual bool is_simple_exception_stub() const { return false; } 3.15 #ifndef PRODUCT 3.16 virtual void print_name(outputStream* out) const = 0; 3.17 #endif 3.18 @@ -484,6 +485,7 @@ 3.19 virtual void emit_code(LIR_Assembler* e); 3.20 virtual CodeEmitInfo* info() const { return _info; } 3.21 virtual bool is_exception_throw_stub() const { return true; } 3.22 + virtual bool is_simple_exception_stub() const { return true; } 3.23 virtual void visit(LIR_OpVisitState* visitor) { 3.24 if (_obj->is_valid()) visitor->do_input(_obj); 3.25 visitor->do_slow_case(_info);
4.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Mon Nov 21 22:56:59 2016 -0800 4.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Tue Dec 13 14:37:04 2016 -0500 4.3 @@ -1823,6 +1823,20 @@ 4.4 log->identify(target), 4.5 Bytecodes::name(code)); 4.6 4.7 + // invoke-special-super 4.8 + if (bc_raw == Bytecodes::_invokespecial && !target->is_object_initializer()) { 4.9 + ciInstanceKlass* sender_klass = 4.10 + calling_klass->is_anonymous() ? calling_klass->host_klass() : 4.11 + calling_klass; 4.12 + if (sender_klass->is_interface()) { 4.13 + int index = state()->stack_size() - (target->arg_size_no_receiver() + 1); 4.14 + Value receiver = state()->stack_at(index); 4.15 + CheckCast* c = new CheckCast(sender_klass, receiver, copy_state_before()); 4.16 + c->set_invokespecial_receiver_check(); 4.17 + state()->stack_at_put(index, append_split(c)); 4.18 + } 4.19 + } 4.20 + 4.21 // Some methods are obviously bindable without any type checks so 4.22 // convert them directly to an invokespecial or invokestatic. 4.23 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
5.1 --- a/src/share/vm/c1/c1_Instruction.hpp Mon Nov 21 22:56:59 2016 -0800 5.2 +++ b/src/share/vm/c1/c1_Instruction.hpp Tue Dec 13 14:37:04 2016 -0500 5.3 @@ -381,6 +381,7 @@ 5.4 UnorderedIsTrueFlag, 5.5 NeedsPatchingFlag, 5.6 ThrowIncompatibleClassChangeErrorFlag, 5.7 + InvokeSpecialReceiverCheckFlag, 5.8 ProfileMDOFlag, 5.9 IsLinkedInBlockFlag, 5.10 NeedsRangeCheckFlag, 5.11 @@ -1456,6 +1457,16 @@ 5.12 bool is_incompatible_class_change_check() const { 5.13 return check_flag(ThrowIncompatibleClassChangeErrorFlag); 5.14 } 5.15 + void set_invokespecial_receiver_check() { 5.16 + set_flag(InvokeSpecialReceiverCheckFlag, true); 5.17 + } 5.18 + bool is_invokespecial_receiver_check() const { 5.19 + return check_flag(InvokeSpecialReceiverCheckFlag); 5.20 + } 5.21 + 5.22 + virtual bool needs_exception_state() const { 5.23 + return !is_invokespecial_receiver_check(); 5.24 + } 5.25 5.26 ciType* declared_type() const; 5.27 };
6.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Mon Nov 21 22:56:59 2016 -0800 6.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Tue Dec 13 14:37:04 2016 -0500 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -58,6 +58,7 @@ 6.11 _nonstatic_field_size = ik->nonstatic_field_size(); 6.12 _has_nonstatic_fields = ik->has_nonstatic_fields(); 6.13 _has_default_methods = ik->has_default_methods(); 6.14 + _is_anonymous = ik->is_anonymous(); 6.15 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: 6.16 6.17 _implementor = NULL; // we will fill these lazily 6.18 @@ -100,6 +101,7 @@ 6.19 _nonstatic_field_size = -1; 6.20 _has_nonstatic_fields = false; 6.21 _nonstatic_fields = NULL; 6.22 + _is_anonymous = false; 6.23 _loader = loader; 6.24 _protection_domain = protection_domain; 6.25 _is_shared = false; 6.26 @@ -591,6 +593,16 @@ 6.27 return impl; 6.28 } 6.29 6.30 +ciInstanceKlass* ciInstanceKlass::host_klass() { 6.31 + assert(is_loaded(), "must be loaded"); 6.32 + if (is_anonymous()) { 6.33 + VM_ENTRY_MARK 6.34 + Klass* host_klass = get_instanceKlass()->host_klass(); 6.35 + return CURRENT_ENV->get_instance_klass(host_klass); 6.36 + } 6.37 + return NULL; 6.38 +} 6.39 + 6.40 // Utility class for printing of the contents of the static fields for 6.41 // use by compilation replay. It only prints out the information that 6.42 // could be consumed by the compiler, so for primitive types it prints
7.1 --- a/src/share/vm/ci/ciInstanceKlass.hpp Mon Nov 21 22:56:59 2016 -0800 7.2 +++ b/src/share/vm/ci/ciInstanceKlass.hpp Tue Dec 13 14:37:04 2016 -0500 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -53,6 +53,7 @@ 7.11 bool _has_subklass; 7.12 bool _has_nonstatic_fields; 7.13 bool _has_default_methods; 7.14 + bool _is_anonymous; 7.15 7.16 ciFlags _flags; 7.17 jint _nonstatic_field_size; 7.18 @@ -177,6 +178,10 @@ 7.19 return _has_default_methods; 7.20 } 7.21 7.22 + bool is_anonymous() { 7.23 + return _is_anonymous; 7.24 + } 7.25 + 7.26 ciInstanceKlass* get_canonical_holder(int offset); 7.27 ciField* get_field_by_offset(int field_offset, bool is_static); 7.28 ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); 7.29 @@ -248,6 +253,8 @@ 7.30 return NULL; 7.31 } 7.32 7.33 + ciInstanceKlass* host_klass(); 7.34 + 7.35 // Dump the current state of this klass for compilation replay. 7.36 virtual void dump_replay_data(outputStream* out); 7.37 };
8.1 --- a/src/share/vm/ci/ciMethod.cpp Mon Nov 21 22:56:59 2016 -0800 8.2 +++ b/src/share/vm/ci/ciMethod.cpp Tue Dec 13 14:37:04 2016 -0500 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -948,6 +948,13 @@ 8.11 } 8.12 8.13 // ------------------------------------------------------------------ 8.14 +// ciMethod::is_object_initializer 8.15 +// 8.16 +bool ciMethod::is_object_initializer() const { 8.17 + return name() == ciSymbol::object_initializer_name(); 8.18 +} 8.19 + 8.20 +// ------------------------------------------------------------------ 8.21 // ciMethod::has_member_arg 8.22 // 8.23 // Return true if the method is a linker intrinsic like _linkToVirtual.
9.1 --- a/src/share/vm/ci/ciMethod.hpp Mon Nov 21 22:56:59 2016 -0800 9.2 +++ b/src/share/vm/ci/ciMethod.hpp Tue Dec 13 14:37:04 2016 -0500 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -316,6 +316,7 @@ 9.11 bool can_be_statically_bound() const { return _can_be_statically_bound; } 9.12 bool is_boxing_method() const; 9.13 bool is_unboxing_method() const; 9.14 + bool is_object_initializer() const; 9.15 9.16 // Replay data methods 9.17 void dump_name_as_ascii(outputStream* st);
10.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Mon Nov 21 22:56:59 2016 -0800 10.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Tue Dec 13 14:37:04 2016 -0500 10.3 @@ -690,7 +690,8 @@ 10.4 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) { 10.5 // extract receiver from the outgoing argument list if necessary 10.6 Handle receiver(thread, NULL); 10.7 - if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { 10.8 + if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface || 10.9 + bytecode == Bytecodes::_invokespecial) { 10.10 ResourceMark rm(thread); 10.11 methodHandle m (thread, method(thread)); 10.12 Bytecode_invoke call(m, bci(thread)); 10.13 @@ -756,16 +757,25 @@ 10.14 int index = info.resolved_method()->itable_index(); 10.15 assert(info.itable_index() == index, ""); 10.16 } 10.17 + } else if (bytecode == Bytecodes::_invokespecial) { 10.18 + assert(info.call_kind() == CallInfo::direct_call, "must be direct call"); 10.19 } else { 10.20 assert(info.call_kind() == CallInfo::direct_call || 10.21 info.call_kind() == CallInfo::vtable_call, ""); 10.22 } 10.23 #endif 10.24 + // Get sender or sender's host_klass, and only set cpCache entry to resolved if 10.25 + // it is not an interface. The receiver for invokespecial calls within interface 10.26 + // methods must be checked for every call. 10.27 + InstanceKlass* sender = pool->pool_holder(); 10.28 + sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; 10.29 + 10.30 switch (info.call_kind()) { 10.31 case CallInfo::direct_call: 10.32 cache_entry(thread)->set_direct_call( 10.33 bytecode, 10.34 - info.resolved_method()); 10.35 + info.resolved_method(), 10.36 + sender->is_interface()); 10.37 break; 10.38 case CallInfo::vtable_call: 10.39 cache_entry(thread)->set_vtable_call(
11.1 --- a/src/share/vm/interpreter/linkResolver.cpp Mon Nov 21 22:56:59 2016 -0800 11.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Tue Dec 13 14:37:04 2016 -0500 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -913,11 +913,11 @@ 11.11 } 11.12 11.13 11.14 -void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, 11.15 +void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name, 11.16 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { 11.17 methodHandle resolved_method; 11.18 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 11.19 - runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK); 11.20 + runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK); 11.21 } 11.22 11.23 // throws linktime exceptions 11.24 @@ -1016,7 +1016,7 @@ 11.25 11.26 // throws runtime exceptions 11.27 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, 11.28 - KlassHandle current_klass, bool check_access, TRAPS) { 11.29 + KlassHandle current_klass, Handle recv, bool check_access, TRAPS) { 11.30 11.31 // resolved method is selected method unless we have an old-style lookup 11.32 // for a superclass method 11.33 @@ -1024,21 +1024,19 @@ 11.34 // no checks for shadowing 11.35 methodHandle sel_method(THREAD, resolved_method()); 11.36 11.37 + if (check_access && 11.38 + // check if the method is not <init> 11.39 + resolved_method->name() != vmSymbols::object_initializer_name()) { 11.40 + 11.41 // check if this is an old-style super call and do a new lookup if so 11.42 - { KlassHandle method_klass = KlassHandle(THREAD, 11.43 - resolved_method->method_holder()); 11.44 - 11.45 - if (check_access && 11.46 // a) check if ACC_SUPER flag is set for the current class 11.47 - (current_klass->is_super() || !AllowNonVirtualCalls) && 11.48 + if ((current_klass->is_super() || !AllowNonVirtualCalls) && 11.49 // b) check if the class of the resolved_klass is a superclass 11.50 // (not supertype in order to exclude interface classes) of the current class. 11.51 // This check is not performed for super.invoke for interface methods 11.52 // in super interfaces. 11.53 current_klass->is_subclass_of(resolved_klass()) && 11.54 - current_klass() != resolved_klass() && 11.55 - // c) check if the method is not <init> 11.56 - resolved_method->name() != vmSymbols::object_initializer_name()) { 11.57 + current_klass() != resolved_klass()) { 11.58 // Lookup super method 11.59 KlassHandle super_klass(THREAD, current_klass->super()); 11.60 lookup_instance_method_in_klasses(sel_method, super_klass, 11.61 @@ -1053,6 +1051,27 @@ 11.62 resolved_method->signature())); 11.63 } 11.64 } 11.65 + 11.66 + // Check that the class of objectref (the receiver) is the current class or interface, 11.67 + // or a subtype of the current class or interface (the sender), otherwise invokespecial 11.68 + // throws IllegalAccessError. 11.69 + // The verifier checks that the sender is a subtype of the class in the I/MR operand. 11.70 + // The verifier also checks that the receiver is a subtype of the sender, if the sender is 11.71 + // a class. If the sender is an interface, the check has to be performed at runtime. 11.72 + InstanceKlass* sender = InstanceKlass::cast(current_klass()); 11.73 + sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; 11.74 + if (sender->is_interface() && recv.not_null()) { 11.75 + Klass* receiver_klass = recv->klass(); 11.76 + if (!receiver_klass->is_subtype_of(sender)) { 11.77 + ResourceMark rm(THREAD); 11.78 + char buf[500]; 11.79 + jio_snprintf(buf, sizeof(buf), 11.80 + "Receiver class %s must be the current class or a subtype of interface %s", 11.81 + receiver_klass->name()->as_C_string(), 11.82 + sender->name()->as_C_string()); 11.83 + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf); 11.84 + } 11.85 + } 11.86 } 11.87 11.88 // check if not static 11.89 @@ -1479,7 +1498,7 @@ 11.90 bool check_access) { 11.91 EXCEPTION_MARK; 11.92 CallInfo info; 11.93 - resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD); 11.94 + resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD); 11.95 if (HAS_PENDING_EXCEPTION) { 11.96 CLEAR_PENDING_EXCEPTION; 11.97 return methodHandle(); 11.98 @@ -1495,7 +1514,7 @@ 11.99 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { 11.100 switch (byte) { 11.101 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; 11.102 - case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break; 11.103 + case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break; 11.104 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; 11.105 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break; 11.106 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; 11.107 @@ -1526,13 +1545,13 @@ 11.108 } 11.109 11.110 11.111 -void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { 11.112 +void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { 11.113 KlassHandle resolved_klass; 11.114 Symbol* method_name = NULL; 11.115 Symbol* method_signature = NULL; 11.116 KlassHandle current_klass; 11.117 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); 11.118 - resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 11.119 + resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 11.120 } 11.121 11.122
12.1 --- a/src/share/vm/interpreter/linkResolver.hpp Mon Nov 21 22:56:59 2016 -0800 12.2 +++ b/src/share/vm/interpreter/linkResolver.hpp Tue Dec 13 14:37:04 2016 -0500 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -142,7 +142,7 @@ 12.11 static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS); 12.12 static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 12.13 12.14 - static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS); 12.15 + static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, Handle recv, bool check_access, TRAPS); 12.16 static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS); 12.17 static void runtime_resolve_interface_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS); 12.18 12.19 @@ -173,7 +173,7 @@ 12.20 // resolved_klass = specified class (i.e., static receiver class) 12.21 // current_klass = sending method holder (i.e., class containing the method containing the call being resolved) 12.22 static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS); 12.23 - static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 12.24 + static void resolve_special_call (CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 12.25 static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); 12.26 static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); 12.27 static void resolve_handle_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS); 12.28 @@ -196,7 +196,7 @@ 12.29 12.30 // runtime resolving from constant pool 12.31 static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS); 12.32 - static void resolve_invokespecial (CallInfo& result, constantPoolHandle pool, int index, TRAPS); 12.33 + static void resolve_invokespecial (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS); 12.34 static void resolve_invokevirtual (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS); 12.35 static void resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS); 12.36 static void resolve_invokedynamic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
13.1 --- a/src/share/vm/oops/cpCache.cpp Mon Nov 21 22:56:59 2016 -0800 13.2 +++ b/src/share/vm/oops/cpCache.cpp Tue Dec 13 14:37:04 2016 -0500 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -144,7 +144,8 @@ 13.11 13.12 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, 13.13 methodHandle method, 13.14 - int vtable_index) { 13.15 + int vtable_index, 13.16 + bool sender_is_interface) { 13.17 bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean 13.18 assert(method->interpreter_entry() != NULL, "should have been set at this point"); 13.19 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); 13.20 @@ -208,7 +209,13 @@ 13.21 if (byte_no == 1) { 13.22 assert(invoke_code != Bytecodes::_invokevirtual && 13.23 invoke_code != Bytecodes::_invokeinterface, ""); 13.24 + // Don't mark invokespecial to method as resolved if sender is an interface. The receiver 13.25 + // has to be checked that it is a subclass of the current class every time this bytecode 13.26 + // is executed. 13.27 + if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface || 13.28 + method->name() == vmSymbols::object_initializer_name()) { 13.29 set_bytecode_1(invoke_code); 13.30 + } 13.31 } else if (byte_no == 2) { 13.32 if (change_to_virtual) { 13.33 assert(invoke_code == Bytecodes::_invokeinterface, ""); 13.34 @@ -238,17 +245,18 @@ 13.35 NOT_PRODUCT(verify(tty)); 13.36 } 13.37 13.38 -void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) { 13.39 +void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method, 13.40 + bool sender_is_interface) { 13.41 int index = Method::nonvirtual_vtable_index; 13.42 // index < 0; FIXME: inline and customize set_direct_or_vtable_call 13.43 - set_direct_or_vtable_call(invoke_code, method, index); 13.44 + set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface); 13.45 } 13.46 13.47 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { 13.48 // either the method is a miranda or its holder should accept the given index 13.49 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); 13.50 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call 13.51 - set_direct_or_vtable_call(invoke_code, method, index); 13.52 + set_direct_or_vtable_call(invoke_code, method, index, false); 13.53 } 13.54 13.55 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
14.1 --- a/src/share/vm/oops/cpCache.hpp Mon Nov 21 22:56:59 2016 -0800 14.2 +++ b/src/share/vm/oops/cpCache.hpp Tue Dec 13 14:37:04 2016 -0500 14.3 @@ -229,13 +229,15 @@ 14.4 void set_direct_or_vtable_call( 14.5 Bytecodes::Code invoke_code, // the bytecode used for invoking the method 14.6 methodHandle method, // the method/prototype if any (NULL, otherwise) 14.7 - int vtable_index // the vtable index if any, else negative 14.8 + int vtable_index, // the vtable index if any, else negative 14.9 + bool sender_is_interface 14.10 ); 14.11 14.12 public: 14.13 void set_direct_call( // sets entry to exact concrete method entry 14.14 Bytecodes::Code invoke_code, // the bytecode used for invoking the method 14.15 - methodHandle method // the method to call 14.16 + methodHandle method, // the method to call 14.17 + bool sender_is_interface 14.18 ); 14.19 14.20 void set_vtable_call( // sets entry to vtable index
15.1 --- a/src/share/vm/opto/doCall.cpp Mon Nov 21 22:56:59 2016 -0800 15.2 +++ b/src/share/vm/opto/doCall.cpp Tue Dec 13 14:37:04 2016 -0500 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -477,6 +477,30 @@ 15.11 speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL; 15.12 } 15.13 15.14 + // invoke-super-special 15.15 + if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) { 15.16 + ciInstanceKlass* calling_klass = method()->holder(); 15.17 + ciInstanceKlass* sender_klass = 15.18 + calling_klass->is_anonymous() ? calling_klass->host_klass() : 15.19 + calling_klass; 15.20 + if (sender_klass->is_interface()) { 15.21 + Node* receiver_node = stack(sp() - nargs); 15.22 + Node* cls_node = makecon(TypeKlassPtr::make(sender_klass)); 15.23 + Node* bad_type_ctrl = NULL; 15.24 + Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl); 15.25 + if (bad_type_ctrl != NULL) { 15.26 + PreserveJVMState pjvms(this); 15.27 + set_control(bad_type_ctrl); 15.28 + uncommon_trap(Deoptimization::Reason_class_check, 15.29 + Deoptimization::Action_none); 15.30 + } 15.31 + if (stopped()) { 15.32 + return; // MUST uncommon-trap? 15.33 + } 15.34 + set_stack(sp() - nargs, casted_receiver); 15.35 + } 15.36 + } 15.37 + 15.38 // Note: It's OK to try to inline a virtual call. 15.39 // The call generator will not attempt to inline a polymorphic call 15.40 // unless it knows how to optimize the receiver dispatch.
16.1 --- a/src/share/vm/prims/methodHandles.cpp Mon Nov 21 22:56:59 2016 -0800 16.2 +++ b/src/share/vm/prims/methodHandles.cpp Tue Dec 13 14:37:04 2016 -0500 16.3 @@ -1,5 +1,5 @@ 16.4 /* 16.5 - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 16.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 * 16.9 * This code is free software; you can redistribute it and/or modify it 16.10 @@ -679,7 +679,7 @@ 16.11 defc, name, type, caller, THREAD); 16.12 } else if (ref_kind == JVM_REF_invokeSpecial) { 16.13 LinkResolver::resolve_special_call(result, 16.14 - defc, name, type, caller, caller.not_null(), THREAD); 16.15 + Handle(), defc, name, type, caller, caller.not_null(), THREAD); 16.16 } else if (ref_kind == JVM_REF_invokeVirtual) { 16.17 LinkResolver::resolve_virtual_call(result, Handle(), defc, 16.18 defc, name, type, caller, caller.not_null(), false, THREAD); 16.19 @@ -706,7 +706,7 @@ 16.20 assert(!HAS_PENDING_EXCEPTION, ""); 16.21 if (name == vmSymbols::object_initializer_name()) { 16.22 LinkResolver::resolve_special_call(result, 16.23 - defc, name, type, caller, caller.not_null(), THREAD); 16.24 + Handle(), defc, name, type, caller, caller.not_null(), THREAD); 16.25 } else { 16.26 break; // will throw after end of switch 16.27 }
17.1 --- a/src/share/vm/runtime/javaCalls.cpp Mon Nov 21 22:56:59 2016 -0800 17.2 +++ b/src/share/vm/runtime/javaCalls.cpp Tue Dec 13 14:37:04 2016 -0500 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -231,7 +231,7 @@ 17.11 17.12 void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { 17.13 CallInfo callinfo; 17.14 - LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK); 17.15 + LinkResolver::resolve_special_call(callinfo, args->receiver(), klass, name, signature, KlassHandle(), false, CHECK); 17.16 methodHandle method = callinfo.selected_method(); 17.17 assert(method.not_null(), "should have thrown exception"); 17.18