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