javaCalls.hpp revision 2062:3582bf76420e
1213904Sandreast/* 2213904Sandreast * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3213904Sandreast * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4213904Sandreast * 5213904Sandreast * This code is free software; you can redistribute it and/or modify it 6213904Sandreast * under the terms of the GNU General Public License version 2 only, as 7213904Sandreast * published by the Free Software Foundation. 8213904Sandreast * 9213904Sandreast * This code is distributed in the hope that it will be useful, but WITHOUT 10213904Sandreast * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11213904Sandreast * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12213904Sandreast * version 2 for more details (a copy is included in the LICENSE file that 13213904Sandreast * accompanied this code). 14213904Sandreast * 15213904Sandreast * You should have received a copy of the GNU General Public License version 16213904Sandreast * 2 along with this work; if not, write to the Free Software Foundation, 17213904Sandreast * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18213904Sandreast * 19213904Sandreast * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20213904Sandreast * or visit www.oracle.com if you need additional information or have any 21213904Sandreast * questions. 22213904Sandreast * 23213904Sandreast */ 24213904Sandreast 25213904Sandreast#ifndef SHARE_VM_RUNTIME_JAVACALLS_HPP 26213904Sandreast#define SHARE_VM_RUNTIME_JAVACALLS_HPP 27213904Sandreast 28213904Sandreast#include "memory/allocation.hpp" 29213904Sandreast#include "oops/methodOop.hpp" 30213904Sandreast#include "runtime/handles.hpp" 31213904Sandreast#include "runtime/javaFrameAnchor.hpp" 32213904Sandreast#include "runtime/vmThread.hpp" 33213904Sandreast#ifdef TARGET_ARCH_x86 34213904Sandreast# include "jniTypes_x86.hpp" 35213904Sandreast#endif 36213904Sandreast#ifdef TARGET_ARCH_sparc 37213904Sandreast# include "jniTypes_sparc.hpp" 38213904Sandreast#endif 39213904Sandreast#ifdef TARGET_ARCH_zero 40213904Sandreast# include "jniTypes_zero.hpp" 41213904Sandreast#endif 42213904Sandreast#ifdef TARGET_OS_FAMILY_linux 43213904Sandreast# include "thread_linux.inline.hpp" 44213904Sandreast#endif 45213904Sandreast#ifdef TARGET_OS_FAMILY_solaris 46213904Sandreast# include "thread_solaris.inline.hpp" 47213904Sandreast#endif 48213904Sandreast#ifdef TARGET_OS_FAMILY_windows 49213904Sandreast# include "thread_windows.inline.hpp" 50213904Sandreast#endif 51213904Sandreast 52222458Snwhitehorn// A JavaCallWrapper is constructed before each JavaCall and destructed after the call. 53213904Sandreast// Its purpose is to allocate/deallocate a new handle block and to save/restore the last 54213904Sandreast// Java fp/sp. A pointer to the JavaCallWrapper is stored on the stack. 55213904Sandreast 56213904Sandreastclass JavaCallWrapper: StackObj { 57213904Sandreast friend class VMStructs; 58213904Sandreast private: 59213904Sandreast JavaThread* _thread; // the thread to which this call belongs 60213904Sandreast JNIHandleBlock* _handles; // the saved handle block 61213904Sandreast methodOop _callee_method; // to be able to collect arguments if entry frame is top frame 62213904Sandreast oop _receiver; // the receiver of the call (if a non-static call) 63222458Snwhitehorn 64222458Snwhitehorn JavaFrameAnchor _anchor; // last thread anchor state that we must restore 65222458Snwhitehorn 66222458Snwhitehorn JavaValue* _result; // result value 67222458Snwhitehorn 68222458Snwhitehorn public: 69222458Snwhitehorn // Construction/destruction 70213904Sandreast JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS); 71222458Snwhitehorn ~JavaCallWrapper(); 72213904Sandreast 73213904Sandreast // Accessors 74213904Sandreast JavaThread* thread() const { return _thread; } 75213904Sandreast JNIHandleBlock* handles() const { return _handles; } 76213904Sandreast 77213904Sandreast JavaFrameAnchor* anchor(void) { return &_anchor; } 78213904Sandreast 79213904Sandreast JavaValue* result() const { return _result; } 80213904Sandreast // GC support 81213904Sandreast methodOop callee_method() { return _callee_method; } 82213904Sandreast oop receiver() { return _receiver; } 83213904Sandreast void oops_do(OopClosure* f); 84213904Sandreast 85213904Sandreast}; 86213904Sandreast 87213904Sandreast 88213904Sandreast// Encapsulates arguments to a JavaCall (faster, safer, and more convenient than using var-args) 89213904Sandreastclass JavaCallArguments : public StackObj { 90213904Sandreast private: 91213904Sandreast enum Constants { 92213904Sandreast _default_size = 8 // Must be at least # of arguments in JavaCalls methods 93213904Sandreast }; 94213904Sandreast 95213904Sandreast intptr_t _value_buffer [_default_size + 1]; 96213904Sandreast bool _is_oop_buffer[_default_size + 1]; 97213904Sandreast 98222658Sandreast intptr_t* _value; 99213904Sandreast bool* _is_oop; 100213904Sandreast int _size; 101213904Sandreast int _max_size; 102213904Sandreast bool _start_at_zero; // Support late setting of receiver 103213904Sandreast 104213904Sandreast void initialize() { 105222658Sandreast // Starts at first element to support set_receiver. 106222658Sandreast _value = &_value_buffer[1]; 107222658Sandreast _is_oop = &_is_oop_buffer[1]; 108222658Sandreast 109222658Sandreast _max_size = _default_size; 110222658Sandreast _size = 0; 111222658Sandreast _start_at_zero = false; 112222658Sandreast } 113222658Sandreast 114222658Sandreast public: 115222658Sandreast JavaCallArguments() { initialize(); } 116222658Sandreast 117222658Sandreast JavaCallArguments(Handle receiver) { 118222658Sandreast initialize(); 119213904Sandreast push_oop(receiver); 120213904Sandreast } 121213904Sandreast 122213904Sandreast JavaCallArguments(int max_size) { 123213904Sandreast if (max_size > _default_size) { 124213904Sandreast _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1); 125213904Sandreast _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1); 126213904Sandreast 127213904Sandreast // Reserve room for potential receiver in value and is_oop 128213904Sandreast _value++; _is_oop++; 129213904Sandreast 130213904Sandreast _max_size = max_size; 131213904Sandreast _size = 0; 132213904Sandreast _start_at_zero = false; 133213904Sandreast } else { 134213904Sandreast initialize(); 135216360Sandreast } 136216360Sandreast } 137213904Sandreast 138213904Sandreast inline void push_oop(Handle h) { _is_oop[_size] = true; 139213904Sandreast JNITypes::put_obj((oop)h.raw_value(), _value, _size); } 140213904Sandreast 141213904Sandreast inline void push_int(int i) { _is_oop[_size] = false; 142213904Sandreast JNITypes::put_int(i, _value, _size); } 143216360Sandreast 144213904Sandreast inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false; 145213904Sandreast JNITypes::put_double(d, _value, _size); } 146213904Sandreast 147213904Sandreast inline void push_long(jlong l) { _is_oop[_size] = false; _is_oop[_size + 1] = false; 148213904Sandreast JNITypes::put_long(l, _value, _size); } 149213904Sandreast 150213904Sandreast inline void push_float(float f) { _is_oop[_size] = false; 151213904Sandreast JNITypes::put_float(f, _value, _size); } 152213904Sandreast 153213904Sandreast // receiver 154213904Sandreast Handle receiver() { 155213904Sandreast assert(_size > 0, "must at least be one argument"); 156213904Sandreast assert(_is_oop[0], "first argument must be an oop"); 157213904Sandreast assert(_value[0] != 0, "receiver must be not-null"); 158213904Sandreast return Handle((oop*)_value[0], false); 159213904Sandreast } 160213904Sandreast 161213904Sandreast void set_receiver(Handle h) { 162213904Sandreast assert(_start_at_zero == false, "can only be called once"); 163213904Sandreast _start_at_zero = true; 164213904Sandreast _is_oop--; 165213904Sandreast _value--; 166213904Sandreast _size++; 167213904Sandreast _is_oop[0] = true; 168213904Sandreast _value[0] = (intptr_t)h.raw_value(); 169213904Sandreast } 170213904Sandreast 171213904Sandreast // Converts all Handles to oops, and returns a reference to parameter vector 172213904Sandreast intptr_t* parameters() ; 173213904Sandreast int size_of_parameters() const { return _size; } 174213904Sandreast 175213904Sandreast // Verify that pushed arguments fits a given method 176213904Sandreast void verify(methodHandle method, BasicType return_type, Thread *thread); 177213904Sandreast}; 178213904Sandreast 179217560Sandreast// All calls to Java have to go via JavaCalls. Sets up the stack frame 180213904Sandreast// and makes sure that the last_Java_frame pointers are chained correctly. 181213904Sandreast// 182213904Sandreast 183213904Sandreastclass JavaCalls: AllStatic { 184213904Sandreast static void call_helper(JavaValue* result, methodHandle* method, JavaCallArguments* args, TRAPS); 185213904Sandreast public: 186213904Sandreast // Optimized Constuctor call 187213904Sandreast static void call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS); 188213904Sandreast 189213904Sandreast // call_special 190213904Sandreast // ------------ 191213904Sandreast // The receiver must be first oop in argument list 192213904Sandreast static void call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS); 193222658Sandreast 194222658Sandreast static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); // No args 195222658Sandreast static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS); 196222658Sandreast static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS); 197222458Snwhitehorn 198222458Snwhitehorn // virtual call 199213904Sandreast // ------------ 200213904Sandreast 201217560Sandreast // The receiver must be first oop in argument list 202217560Sandreast static void call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS); 203217560Sandreast 204222458Snwhitehorn static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS); // No args 205222458Snwhitehorn static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS); 206217560Sandreast static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS); 207217560Sandreast 208217560Sandreast // Static call 209217560Sandreast // ----------- 210213904Sandreast static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS); 211213904Sandreast 212222458Snwhitehorn static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 213222658Sandreast static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS); 214222658Sandreast static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS); 215222658Sandreast 216222658Sandreast // Low-level interface 217222658Sandreast static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS); 218222658Sandreast}; 219222658Sandreast 220222658Sandreast#endif // SHARE_VM_RUNTIME_JAVACALLS_HPP 221222458Snwhitehorn