< prev index next >
src/share/vm/runtime/javaCalls.cpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -323,13 +323,13 @@
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
// Verify the arguments
if (CheckJNICalls) {
- args->verify(method, result->get_type(), thread);
+ args->verify(method, result->get_type());
}
- else debug_only(args->verify(method, result->get_type(), thread));
+ else debug_only(args->verify(method, result->get_type()));
// Ignore call if method is empty
if (method->is_empty_method()) {
assert(result->get_type() == T_VOID, "an empty method must return a void value");
return;
@@ -427,49 +427,89 @@
//--------------------------------------------------------------------------------------
// Implementation of JavaCallArguments
+inline bool is_value_state_indirect_oop(uint state) {
+ assert(state != JavaCallArguments::value_state_oop,
+ "Checking for handles after removal");
+ assert(state < JavaCallArguments::value_state_limit, "Invalid value state");
+ return state != JavaCallArguments::value_state_primitive;
+}
+
+inline oop resolve_indirect_oop(intptr_t value, uint state) {
+ switch (state) {
+ case JavaCallArguments::value_state_handle:
+ {
+ oop* ptr = reinterpret_cast<oop*>(value);
+ return Handle::raw_resolve(ptr);
+ }
+
+ case JavaCallArguments::value_state_jobject:
+ {
+ jobject obj = reinterpret_cast<jobject>(value);
+ return JNIHandles::resolve(obj);
+ }
+
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+}
+
intptr_t* JavaCallArguments::parameters() {
// First convert all handles to oops
for(int i = 0; i < _size; i++) {
- if (_is_oop[i]) {
- // Handle conversion
- _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i]));
+ uint state = _value_state[i];
+ assert(state != value_state_oop, "Multiple handle conversions");
+ if (is_value_state_indirect_oop(state)) {
+ oop obj = resolve_indirect_oop(_value[i], state);
+ _value[i] = cast_from_oop<intptr_t>(obj);
+ _value_state[i] = value_state_oop;
}
}
// Return argument vector
return _value;
}
class SignatureChekker : public SignatureIterator {
private:
- bool *_is_oop;
int _pos;
BasicType _return_type;
+ u_char* _value_state;
intptr_t* _value;
- Thread* _thread;
public:
bool _is_return;
- SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
- _is_oop = is_oop;
- _is_return = false;
- _return_type = return_type;
- _pos = 0;
- _value = value;
- _thread = thread;
-
+ SignatureChekker(Symbol* signature,
+ BasicType return_type,
+ bool is_static,
+ u_char* value_state,
+ intptr_t* value) :
+ SignatureIterator(signature),
+ _pos(0),
+ _return_type(return_type),
+ _value_state(value_state),
+ _value(value),
+ _is_return(false)
+ {
if (!is_static) {
check_value(true); // Receiver must be an oop
}
}
void check_value(bool type) {
- guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments");
+ uint state = _value_state[_pos++];
+ if (type) {
+ guarantee(is_value_state_indirect_oop(state),
+ "signature does not match pushed arguments");
+ } else {
+ guarantee(state == JavaCallArguments::value_state_primitive,
+ "signature does not match pushed arguments");
+ }
}
void check_doing_return(bool state) { _is_return = state; }
void check_return_type(BasicType t) {
@@ -500,28 +540,23 @@
if (_is_return) {
check_return_type(t);
return;
}
- // verify handle and the oop pointed to by handle
- int p = _pos;
- bool bad = false;
- // If argument is oop
- if (_is_oop[p]) {
- intptr_t v = _value[p];
- if (v != 0 ) {
- size_t t = (size_t)v;
- bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
- if (CheckJNICalls && bad) {
- ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
- }
- }
- // for the regular debug case.
- assert(!bad, "Bad JNI oop argument");
+ intptr_t v = _value[_pos];
+ if (v != 0) {
+ // v is a "handle" referring to an oop, cast to integral type.
+ // There shouldn't be any handles in very low memory.
+ guarantee((size_t)v >= (size_t)os::vm_page_size(),
+ "Bad JNI oop argument");
+ // Verify the pointee.
+ oop vv = resolve_indirect_oop(v, _value_state[_pos]);
+ guarantee(vv->is_oop_or_null(true),
+ "Bad JNI oop argument");
}
- check_value(true);
+ check_value(true); // Verify value state.
}
void do_bool() { check_int(T_BOOLEAN); }
void do_char() { check_int(T_CHAR); }
void do_float() { check_int(T_FLOAT); }
@@ -534,20 +569,23 @@
void do_object(int begin, int end) { check_obj(T_OBJECT); }
void do_array(int begin, int end) { check_obj(T_OBJECT); }
};
-void JavaCallArguments::verify(methodHandle method, BasicType return_type,
- Thread *thread) {
+void JavaCallArguments::verify(methodHandle method, BasicType return_type) {
guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
// Treat T_OBJECT and T_ARRAY as the same
if (return_type == T_ARRAY) return_type = T_OBJECT;
// Check that oop information is correct
Symbol* signature = method->signature();
- SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
+ SignatureChekker sc(signature,
+ return_type,
+ method->is_static(),
+ _value_state,
+ _value);
sc.iterate_parameters();
sc.check_doing_return(true);
sc.iterate_returntype();
}
< prev index next >