< prev index next >
src/share/vm/runtime/javaCalls.hpp
Print this page
rev 12652 : [mq]: kimpatch
*** 1,7 ****
/*
! * Copyright (c) 1997, 2016, 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.
--- 1,7 ----
/*
! * 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.
*** 79,108 ****
enum Constants {
_default_size = 8 // Must be at least # of arguments in JavaCalls methods
};
intptr_t _value_buffer [_default_size + 1];
! bool _is_oop_buffer[_default_size + 1];
intptr_t* _value;
! bool* _is_oop;
int _size;
int _max_size;
bool _start_at_zero; // Support late setting of receiver
JVMCI_ONLY(nmethod* _alternative_target;) // Nmethod that should be called instead of normal target
void initialize() {
// Starts at first element to support set_receiver.
_value = &_value_buffer[1];
! _is_oop = &_is_oop_buffer[1];
_max_size = _default_size;
_size = 0;
_start_at_zero = false;
JVMCI_ONLY(_alternative_target = NULL;)
}
public:
JavaCallArguments() { initialize(); }
JavaCallArguments(Handle receiver) {
initialize();
--- 79,125 ----
enum Constants {
_default_size = 8 // Must be at least # of arguments in JavaCalls methods
};
intptr_t _value_buffer [_default_size + 1];
! u_char _value_state_buffer[_default_size + 1];
intptr_t* _value;
! u_char* _value_state;
int _size;
int _max_size;
bool _start_at_zero; // Support late setting of receiver
JVMCI_ONLY(nmethod* _alternative_target;) // Nmethod that should be called instead of normal target
void initialize() {
// Starts at first element to support set_receiver.
_value = &_value_buffer[1];
! _value_state = &_value_state_buffer[1];
_max_size = _default_size;
_size = 0;
_start_at_zero = false;
JVMCI_ONLY(_alternative_target = NULL;)
}
+ // Helper for push_oop and the like. The value argument is a
+ // "handle" that refers to an oop. We record the address of the
+ // handle rather than the designated oop. The handle is later
+ // resolved to the oop by parameters(). This delays the exposure of
+ // naked oops until it is GC-safe.
+ template<typename T>
+ inline int push_oop_impl(T handle, int size) {
+ // JNITypes::put_obj expects an oop value, so we play fast and
+ // loose with the type system. The cast from handle type to oop
+ // *must* use a C-style cast. In a product build it performs a
+ // reinterpret_cast. In a debug build (more accurately, in a
+ // CHECK_UNHANDLED_OOPS build) it performs a static_cast, invoking
+ // the debug-only oop class's conversion from void* constructor.
+ JNITypes::put_obj((oop)handle, _value, size); // Updates size.
+ return size; // Return the updated size.
+ }
+
public:
JavaCallArguments() { initialize(); }
JavaCallArguments(Handle receiver) {
initialize();
*** 110,123 ****
}
JavaCallArguments(int max_size) {
if (max_size > _default_size) {
_value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
! _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1);
! // Reserve room for potential receiver in value and is_oop
! _value++; _is_oop++;
_max_size = max_size;
_size = 0;
_start_at_zero = false;
JVMCI_ONLY(_alternative_target = NULL;)
--- 127,141 ----
}
JavaCallArguments(int max_size) {
if (max_size > _default_size) {
_value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
! _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1);
! // Reserve room for potential receiver in value and state
! _value++;
! _value_state++;
_max_size = max_size;
_size = 0;
_start_at_zero = false;
JVMCI_ONLY(_alternative_target = NULL;)
*** 134,182 ****
nmethod* alternative_target() {
return _alternative_target;
}
#endif
! inline void push_oop(Handle h) { _is_oop[_size] = true;
! JNITypes::put_obj((oop)h.raw_value(), _value, _size); }
! inline void push_int(int i) { _is_oop[_size] = false;
! JNITypes::put_int(i, _value, _size); }
! inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
! JNITypes::put_double(d, _value, _size); }
! inline void push_long(jlong l) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
! JNITypes::put_long(l, _value, _size); }
! inline void push_float(float f) { _is_oop[_size] = false;
! JNITypes::put_float(f, _value, _size); }
// receiver
Handle receiver() {
assert(_size > 0, "must at least be one argument");
! assert(_is_oop[0], "first argument must be an oop");
assert(_value[0] != 0, "receiver must be not-null");
return Handle((oop*)_value[0], false);
}
void set_receiver(Handle h) {
assert(_start_at_zero == false, "can only be called once");
_start_at_zero = true;
! _is_oop--;
_value--;
_size++;
! _is_oop[0] = true;
! _value[0] = (intptr_t)h.raw_value();
}
// Converts all Handles to oops, and returns a reference to parameter vector
intptr_t* parameters() ;
int size_of_parameters() const { return _size; }
// Verify that pushed arguments fits a given method
! void verify(const methodHandle& method, BasicType return_type, Thread *thread);
};
// All calls to Java have to go via JavaCalls. Sets up the stack frame
// and makes sure that the last_Java_frame pointers are chained correctly.
//
--- 152,227 ----
nmethod* alternative_target() {
return _alternative_target;
}
#endif
! // The possible values for _value_state elements.
! enum {
! value_state_primitive,
! value_state_oop,
! value_state_handle,
! value_state_jobject,
! value_state_limit
! };
! inline void push_oop(Handle h) {
! _value_state[_size] = value_state_handle;
! _size = push_oop_impl(h.raw_value(), _size);
! }
! inline void push_jobject(jobject h) {
! _value_state[_size] = value_state_jobject;
! _size = push_oop_impl(h, _size);
! }
! inline void push_int(int i) {
! _value_state[_size] = value_state_primitive;
! JNITypes::put_int(i, _value, _size);
! }
! inline void push_double(double d) {
! _value_state[_size] = value_state_primitive;
! _value_state[_size + 1] = value_state_primitive;
! JNITypes::put_double(d, _value, _size);
! }
!
! inline void push_long(jlong l) {
! _value_state[_size] = value_state_primitive;
! _value_state[_size + 1] = value_state_primitive;
! JNITypes::put_long(l, _value, _size);
! }
!
! inline void push_float(float f) {
! _value_state[_size] = value_state_primitive;
! JNITypes::put_float(f, _value, _size);
! }
// receiver
Handle receiver() {
assert(_size > 0, "must at least be one argument");
! assert(_value_state[0] == value_state_handle,
! "first argument must be an oop");
assert(_value[0] != 0, "receiver must be not-null");
return Handle((oop*)_value[0], false);
}
void set_receiver(Handle h) {
assert(_start_at_zero == false, "can only be called once");
_start_at_zero = true;
! _value_state--;
_value--;
_size++;
! _value_state[0] = value_state_handle;
! push_oop_impl(h.raw_value(), 0);
}
// Converts all Handles to oops, and returns a reference to parameter vector
intptr_t* parameters() ;
int size_of_parameters() const { return _size; }
// Verify that pushed arguments fits a given method
! void verify(const methodHandle& method, BasicType return_type);
};
// All calls to Java have to go via JavaCalls. Sets up the stack frame
// and makes sure that the last_Java_frame pointers are chained correctly.
//
< prev index next >