1.1 --- a/src/share/vm/runtime/javaCalls.hpp Thu Sep 05 18:40:52 2019 +0800 1.2 +++ b/src/share/vm/runtime/javaCalls.hpp Thu Sep 05 18:52:27 2019 +0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2013, 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 @@ -101,25 +101,42 @@ 1.11 _default_size = 8 // Must be at least # of arguments in JavaCalls methods 1.12 }; 1.13 1.14 - intptr_t _value_buffer [_default_size + 1]; 1.15 - bool _is_oop_buffer[_default_size + 1]; 1.16 + intptr_t _value_buffer [_default_size + 1]; 1.17 + u_char _value_state_buffer[_default_size + 1]; 1.18 1.19 intptr_t* _value; 1.20 - bool* _is_oop; 1.21 + u_char* _value_state; 1.22 int _size; 1.23 int _max_size; 1.24 bool _start_at_zero; // Support late setting of receiver 1.25 1.26 void initialize() { 1.27 // Starts at first element to support set_receiver. 1.28 - _value = &_value_buffer[1]; 1.29 - _is_oop = &_is_oop_buffer[1]; 1.30 + _value = &_value_buffer[1]; 1.31 + _value_state = &_value_state_buffer[1]; 1.32 1.33 _max_size = _default_size; 1.34 _size = 0; 1.35 _start_at_zero = false; 1.36 } 1.37 1.38 + // Helper for push_oop and the like. The value argument is a 1.39 + // "handle" that refers to an oop. We record the address of the 1.40 + // handle rather than the designated oop. The handle is later 1.41 + // resolved to the oop by parameters(). This delays the exposure of 1.42 + // naked oops until it is GC-safe. 1.43 + template<typename T> 1.44 + inline int push_oop_impl(T handle, int size) { 1.45 + // JNITypes::put_obj expects an oop value, so we play fast and 1.46 + // loose with the type system. The cast from handle type to oop 1.47 + // *must* use a C-style cast. In a product build it performs a 1.48 + // reinterpret_cast. In a debug build (more accurately, in a 1.49 + // CHECK_UNHANDLED_OOPS build) it performs a static_cast, invoking 1.50 + // the debug-only oop class's conversion from void* constructor. 1.51 + JNITypes::put_obj((oop)handle, _value, size); // Updates size. 1.52 + return size; // Return the updated size. 1.53 + } 1.54 + 1.55 public: 1.56 JavaCallArguments() { initialize(); } 1.57 1.58 @@ -130,11 +147,12 @@ 1.59 1.60 JavaCallArguments(int max_size) { 1.61 if (max_size > _default_size) { 1.62 - _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1); 1.63 - _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1); 1.64 + _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1); 1.65 + _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1); 1.66 1.67 - // Reserve room for potential receiver in value and is_oop 1.68 - _value++; _is_oop++; 1.69 + // Reserve room for potential receiver in value and state 1.70 + _value++; 1.71 + _value_state++; 1.72 1.73 _max_size = max_size; 1.74 _size = 0; 1.75 @@ -144,25 +162,52 @@ 1.76 } 1.77 } 1.78 1.79 - inline void push_oop(Handle h) { _is_oop[_size] = true; 1.80 - JNITypes::put_obj((oop)h.raw_value(), _value, _size); } 1.81 + // The possible values for _value_state elements. 1.82 + enum { 1.83 + value_state_primitive, 1.84 + value_state_oop, 1.85 + value_state_handle, 1.86 + value_state_jobject, 1.87 + value_state_limit 1.88 + }; 1.89 1.90 - inline void push_int(int i) { _is_oop[_size] = false; 1.91 - JNITypes::put_int(i, _value, _size); } 1.92 + inline void push_oop(Handle h) { 1.93 + _value_state[_size] = value_state_handle; 1.94 + _size = push_oop_impl(h.raw_value(), _size); 1.95 + } 1.96 1.97 - inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false; 1.98 - JNITypes::put_double(d, _value, _size); } 1.99 + inline void push_jobject(jobject h) { 1.100 + _value_state[_size] = value_state_jobject; 1.101 + _size = push_oop_impl(h, _size); 1.102 + } 1.103 1.104 - inline void push_long(jlong l) { _is_oop[_size] = false; _is_oop[_size + 1] = false; 1.105 - JNITypes::put_long(l, _value, _size); } 1.106 + inline void push_int(int i) { 1.107 + _value_state[_size] = value_state_primitive; 1.108 + JNITypes::put_int(i, _value, _size); 1.109 + } 1.110 1.111 - inline void push_float(float f) { _is_oop[_size] = false; 1.112 - JNITypes::put_float(f, _value, _size); } 1.113 + inline void push_double(double d) { 1.114 + _value_state[_size] = value_state_primitive; 1.115 + _value_state[_size + 1] = value_state_primitive; 1.116 + JNITypes::put_double(d, _value, _size); 1.117 + } 1.118 + 1.119 + inline void push_long(jlong l) { 1.120 + _value_state[_size] = value_state_primitive; 1.121 + _value_state[_size + 1] = value_state_primitive; 1.122 + JNITypes::put_long(l, _value, _size); 1.123 + } 1.124 + 1.125 + inline void push_float(float f) { 1.126 + _value_state[_size] = value_state_primitive; 1.127 + JNITypes::put_float(f, _value, _size); 1.128 + } 1.129 1.130 // receiver 1.131 Handle receiver() { 1.132 assert(_size > 0, "must at least be one argument"); 1.133 - assert(_is_oop[0], "first argument must be an oop"); 1.134 + assert(_value_state[0] == value_state_handle, 1.135 + "first argument must be an oop"); 1.136 assert(_value[0] != 0, "receiver must be not-null"); 1.137 return Handle((oop*)_value[0], false); 1.138 } 1.139 @@ -170,11 +215,11 @@ 1.140 void set_receiver(Handle h) { 1.141 assert(_start_at_zero == false, "can only be called once"); 1.142 _start_at_zero = true; 1.143 - _is_oop--; 1.144 + _value_state--; 1.145 _value--; 1.146 _size++; 1.147 - _is_oop[0] = true; 1.148 - _value[0] = (intptr_t)h.raw_value(); 1.149 + _value_state[0] = value_state_handle; 1.150 + push_oop_impl(h.raw_value(), 0); 1.151 } 1.152 1.153 // Converts all Handles to oops, and returns a reference to parameter vector 1.154 @@ -182,7 +227,7 @@ 1.155 int size_of_parameters() const { return _size; } 1.156 1.157 // Verify that pushed arguments fits a given method 1.158 - void verify(methodHandle method, BasicType return_type, Thread *thread); 1.159 + void verify(methodHandle method, BasicType return_type); 1.160 }; 1.161 1.162 // All calls to Java have to go via JavaCalls. Sets up the stack frame