1.1 --- a/src/share/vm/runtime/javaCalls.cpp Thu Sep 05 18:40:52 2019 +0800 1.2 +++ b/src/share/vm/runtime/javaCalls.cpp Thu Sep 05 18:52:27 2019 +0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -325,9 +325,9 @@ 1.11 // Verify the arguments 1.12 1.13 if (CheckJNICalls) { 1.14 - args->verify(method, result->get_type(), thread); 1.15 + args->verify(method, result->get_type()); 1.16 } 1.17 - else debug_only(args->verify(method, result->get_type(), thread)); 1.18 + else debug_only(args->verify(method, result->get_type())); 1.19 1.20 // Ignore call if method is empty 1.21 if (method->is_empty_method()) { 1.22 @@ -429,12 +429,42 @@ 1.23 //-------------------------------------------------------------------------------------- 1.24 // Implementation of JavaCallArguments 1.25 1.26 +inline bool is_value_state_indirect_oop(uint state) { 1.27 + assert(state != JavaCallArguments::value_state_oop, 1.28 + "Checking for handles after removal"); 1.29 + assert(state < JavaCallArguments::value_state_limit, "Invalid value state"); 1.30 + return state != JavaCallArguments::value_state_primitive; 1.31 +} 1.32 + 1.33 +inline oop resolve_indirect_oop(intptr_t value, uint state) { 1.34 + switch (state) { 1.35 + case JavaCallArguments::value_state_handle: 1.36 + { 1.37 + oop* ptr = reinterpret_cast<oop*>(value); 1.38 + return Handle::raw_resolve(ptr); 1.39 + } 1.40 + 1.41 + case JavaCallArguments::value_state_jobject: 1.42 + { 1.43 + jobject obj = reinterpret_cast<jobject>(value); 1.44 + return JNIHandles::resolve(obj); 1.45 + } 1.46 + 1.47 + default: 1.48 + ShouldNotReachHere(); 1.49 + return NULL; 1.50 + } 1.51 +} 1.52 + 1.53 intptr_t* JavaCallArguments::parameters() { 1.54 // First convert all handles to oops 1.55 for(int i = 0; i < _size; i++) { 1.56 - if (_is_oop[i]) { 1.57 - // Handle conversion 1.58 - _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i])); 1.59 + uint state = _value_state[i]; 1.60 + assert(state != value_state_oop, "Multiple handle conversions"); 1.61 + if (is_value_state_indirect_oop(state)) { 1.62 + oop obj = resolve_indirect_oop(_value[i], state); 1.63 + _value[i] = cast_from_oop<intptr_t>(obj); 1.64 + _value_state[i] = value_state_oop; 1.65 } 1.66 } 1.67 // Return argument vector 1.68 @@ -444,30 +474,40 @@ 1.69 1.70 class SignatureChekker : public SignatureIterator { 1.71 private: 1.72 - bool *_is_oop; 1.73 - int _pos; 1.74 - BasicType _return_type; 1.75 - intptr_t* _value; 1.76 - Thread* _thread; 1.77 + int _pos; 1.78 + BasicType _return_type; 1.79 + u_char* _value_state; 1.80 + intptr_t* _value; 1.81 1.82 public: 1.83 bool _is_return; 1.84 1.85 - SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { 1.86 - _is_oop = is_oop; 1.87 - _is_return = false; 1.88 - _return_type = return_type; 1.89 - _pos = 0; 1.90 - _value = value; 1.91 - _thread = thread; 1.92 - 1.93 + SignatureChekker(Symbol* signature, 1.94 + BasicType return_type, 1.95 + bool is_static, 1.96 + u_char* value_state, 1.97 + intptr_t* value) : 1.98 + SignatureIterator(signature), 1.99 + _pos(0), 1.100 + _return_type(return_type), 1.101 + _value_state(value_state), 1.102 + _value(value), 1.103 + _is_return(false) 1.104 + { 1.105 if (!is_static) { 1.106 check_value(true); // Receiver must be an oop 1.107 } 1.108 } 1.109 1.110 void check_value(bool type) { 1.111 - guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); 1.112 + uint state = _value_state[_pos++]; 1.113 + if (type) { 1.114 + guarantee(is_value_state_indirect_oop(state), 1.115 + "signature does not match pushed arguments"); 1.116 + } else { 1.117 + guarantee(state == JavaCallArguments::value_state_primitive, 1.118 + "signature does not match pushed arguments"); 1.119 + } 1.120 } 1.121 1.122 void check_doing_return(bool state) { _is_return = state; } 1.123 @@ -502,24 +542,19 @@ 1.124 return; 1.125 } 1.126 1.127 - // verify handle and the oop pointed to by handle 1.128 - int p = _pos; 1.129 - bool bad = false; 1.130 - // If argument is oop 1.131 - if (_is_oop[p]) { 1.132 - intptr_t v = _value[p]; 1.133 - if (v != 0 ) { 1.134 - size_t t = (size_t)v; 1.135 - bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true); 1.136 - if (CheckJNICalls && bad) { 1.137 - ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); 1.138 - } 1.139 - } 1.140 - // for the regular debug case. 1.141 - assert(!bad, "Bad JNI oop argument"); 1.142 + intptr_t v = _value[_pos]; 1.143 + if (v != 0) { 1.144 + // v is a "handle" referring to an oop, cast to integral type. 1.145 + // There shouldn't be any handles in very low memory. 1.146 + guarantee((size_t)v >= (size_t)os::vm_page_size(), 1.147 + "Bad JNI oop argument"); 1.148 + // Verify the pointee. 1.149 + oop vv = resolve_indirect_oop(v, _value_state[_pos]); 1.150 + guarantee(vv->is_oop_or_null(true), 1.151 + "Bad JNI oop argument"); 1.152 } 1.153 1.154 - check_value(true); 1.155 + check_value(true); // Verify value state. 1.156 } 1.157 1.158 void do_bool() { check_int(T_BOOLEAN); } 1.159 @@ -536,8 +571,7 @@ 1.160 }; 1.161 1.162 1.163 -void JavaCallArguments::verify(methodHandle method, BasicType return_type, 1.164 - Thread *thread) { 1.165 +void JavaCallArguments::verify(methodHandle method, BasicType return_type) { 1.166 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); 1.167 1.168 // Treat T_OBJECT and T_ARRAY as the same 1.169 @@ -546,7 +580,11 @@ 1.170 // Check that oop information is correct 1.171 Symbol* signature = method->signature(); 1.172 1.173 - SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); 1.174 + SignatureChekker sc(signature, 1.175 + return_type, 1.176 + method->is_static(), 1.177 + _value_state, 1.178 + _value); 1.179 sc.iterate_parameters(); 1.180 sc.check_doing_return(true); 1.181 sc.iterate_returntype();