< prev index next > src/hotspot/share/runtime/javaCalls.cpp
Print this page
#include "interpreter/interpreter.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/universe.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/inlineKlass.hpp"
#include "prims/jniCheck.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
// Helper methods
static BasicType runtime_type_from(JavaValue* result) {
switch (result->get_type()) {
! case T_BOOLEAN: // fall through
! case T_CHAR : // fall through
! case T_SHORT : // fall through
! case T_INT : // fall through
#ifndef _LP64
! case T_OBJECT : // fall through
! case T_ARRAY : // fall through
#endif
! case T_BYTE : // fall through
! case T_VOID : return T_INT;
! case T_LONG : return T_LONG;
! case T_FLOAT : return T_FLOAT;
! case T_DOUBLE : return T_DOUBLE;
#ifdef _LP64
! case T_ARRAY : // fall through
! case T_OBJECT: return T_OBJECT;
#endif
default:
ShouldNotReachHere();
return T_ILLEGAL;
}
// Helper methods
static BasicType runtime_type_from(JavaValue* result) {
switch (result->get_type()) {
! case T_BOOLEAN : // fall through
! case T_CHAR : // fall through
! case T_SHORT : // fall through
! case T_INT : // fall through
#ifndef _LP64
! case T_OBJECT : // fall through
! case T_ARRAY : // fall through
+ case T_PRIMITIVE_OBJECT: // fall through
#endif
! case T_BYTE : // fall through
! case T_VOID : return T_INT;
! case T_LONG : return T_LONG;
! case T_FLOAT : return T_FLOAT;
! case T_DOUBLE : return T_DOUBLE;
#ifdef _LP64
! case T_ARRAY : // fall through
! case T_OBJECT : return T_OBJECT;
+ case T_PRIMITIVE_OBJECT: return T_PRIMITIVE_OBJECT;
#endif
default:
ShouldNotReachHere();
return T_ILLEGAL;
}
// ============ allocate and initialize new object instance ============
Handle JavaCalls::construct_new_instance(InstanceKlass* klass, Symbol* constructor_signature, JavaCallArguments* args, TRAPS) {
klass->initialize(CHECK_NH); // Quick no-op if already initialized.
+
+ // Special case for factory methods
+ if (EnableValhalla && !constructor_signature->is_void_method_signature()) {
+ guarantee(klass->is_inline_klass(), "inline classes must use factory methods");
+ JavaValue factory_result(T_OBJECT);
+ JavaCalls::call_static(&factory_result, klass,
+ vmSymbols::inline_factory_name(),
+ constructor_signature, args, CHECK_NH);
+ return Handle(THREAD, factory_result.get_oop());
+ }
+
+ // main branch of code creates a non-inline object:
+ assert(!klass->is_inline_klass(), "classic constructors are only for non-inline classes");
Handle obj = klass->allocate_instance_handle(CHECK_NH);
JavaValue void_result(T_VOID);
args->set_receiver(obj); // inserts <obj> as the first argument.
JavaCalls::call_special(&void_result, klass,
vmSymbols::object_initializer_name(),
} else {
// Touch pages checked if the OS needs them to be touched to be mapped.
os::map_stack_shadow_pages(sp);
}
+ jobject value_buffer = nullptr;
+ if (InlineTypeReturnedAsFields && (result->get_type() == T_PRIMITIVE_OBJECT || result->get_type() == T_OBJECT)) {
+ // Pre allocate a buffered inline type in case the result is returned
+ // flattened by compiled code
+ InlineKlass* vk = method->returns_inline_type(thread);
+ if (vk != nullptr && vk->can_be_returned_as_fields()) {
+ oop instance = vk->allocate_instance(CHECK);
+ value_buffer = JNIHandles::make_local(thread, instance);
+ result->set_jobject(value_buffer);
+ }
+ }
+
// do call
{ JavaCallWrapper link(method, receiver, result, CHECK);
{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner
// NOTE: if we move the computation of the result_val_address inside
// Restore possible oop return
if (oop_result_flag) {
result->set_oop(thread->vm_result());
thread->set_vm_result(nullptr);
+ JNIHandles::destroy_local(value_buffer);
}
}
//--------------------------------------------------------------------------------------
case T_LONG:
case T_DOUBLE:
check_double_word(); break;
case T_ARRAY:
case T_OBJECT:
+ case T_PRIMITIVE_OBJECT:
check_reference(); break;
default:
ShouldNotReachHere();
}
}
void JavaCallArguments::verify(const 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 (is_reference_type(return_type)) return_type = T_OBJECT;
// Check that oop information is correct
Symbol* signature = method->signature();
SignatureChekker sc(signature,
void JavaCallArguments::verify(const 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,
< prev index next >