javaCalls.hpp revision 0:a61af66fc99e
1/*
2 * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25// A JavaCallWrapper is constructed before each JavaCall and destructed after the call.
26// Its purpose is to allocate/deallocate a new handle block and to save/restore the last
27// Java fp/sp. A pointer to the JavaCallWrapper is stored on the stack.
28
29class JavaCallWrapper: StackObj {
30  friend class VMStructs;
31 private:
32  JavaThread*      _thread;                 // the thread to which this call belongs
33  JNIHandleBlock*  _handles;                // the saved handle block
34  methodOop        _callee_method;          // to be able to collect arguments if entry frame is top frame
35  oop              _receiver;               // the receiver of the call (if a non-static call)
36
37  JavaFrameAnchor  _anchor;                 // last thread anchor state that we must restore
38
39  JavaValue*       _result;                 // result value
40
41 public:
42  // Construction/destruction
43   JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS);
44  ~JavaCallWrapper();
45
46  // Accessors
47  JavaThread*      thread() const           { return _thread; }
48  JNIHandleBlock*  handles() const          { return _handles; }
49
50  JavaFrameAnchor* anchor(void)             { return &_anchor; }
51
52  JavaValue*       result() const           { return _result; }
53  // GC support
54  methodOop        callee_method()          { return _callee_method; }
55  oop              receiver()               { return _receiver; }
56  void             oops_do(OopClosure* f);
57
58};
59
60
61// Encapsulates arguments to a JavaCall (faster, safer, and more convenient than using var-args)
62class JavaCallArguments : public StackObj {
63 private:
64  enum Constants {
65   _default_size = 8    // Must be at least # of arguments in JavaCalls methods
66  };
67
68  intptr_t    _value_buffer [_default_size + 1];
69  intptr_t    _parameter_buffer [_default_size*2 + 1];
70  bool        _is_oop_buffer[_default_size + 1];
71
72  intptr_t*   _value;
73  intptr_t*   _parameters;
74  bool*       _is_oop;
75  int         _size;
76  int         _max_size;
77  bool        _start_at_zero;      // Support late setting of receiver
78
79  void initialize() {
80    // Starts at first element to support set_receiver.
81    _value    = &_value_buffer[1];
82    _is_oop   = &_is_oop_buffer[1];
83
84    _parameters = &_parameter_buffer[0];
85    _max_size = _default_size;
86    _size = 0;
87    _start_at_zero = false;
88  }
89
90 public:
91  JavaCallArguments() { initialize(); }
92
93  JavaCallArguments(Handle receiver) {
94    initialize();
95    push_oop(receiver);
96  }
97
98  JavaCallArguments(int max_size) {
99    if (max_size > _default_size) {
100      _value  = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
101      _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1);
102      if (TaggedStackInterpreter) {
103        _parameters  = NEW_RESOURCE_ARRAY(intptr_t, max_size*2 + 1);
104      }
105      // Reserve room for potential receiver in value and is_oop
106      _value++; _is_oop++;
107      _max_size = max_size;
108      _size = 0;
109      _start_at_zero = false;
110    } else {
111      initialize();
112    }
113  }
114
115  inline void push_oop(Handle h)    { _is_oop[_size] = true;
116                               JNITypes::put_obj((oop)h.raw_value(), _value, _size); }
117
118  inline void push_int(int i)       { _is_oop[_size] = false;
119                               JNITypes::put_int(i, _value, _size); }
120
121  inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
122                               JNITypes::put_double(d, _value, _size); }
123
124  inline void push_long(jlong l)    { _is_oop[_size] = false; _is_oop[_size + 1] = false;
125                               JNITypes::put_long(l, _value, _size); }
126
127  inline void push_float(float f)   { _is_oop[_size] = false;
128                               JNITypes::put_float(f, _value, _size); }
129
130  // receiver
131  Handle receiver() {
132    assert(_size > 0, "must at least be one argument");
133    assert(_is_oop[0], "first argument must be an oop");
134    assert(_value[0] != 0, "receiver must be not-null");
135    return Handle((oop*)_value[0], false);
136  }
137
138  void set_receiver(Handle h) {
139    assert(_start_at_zero == false, "can only be called once");
140    _start_at_zero = true;
141    _is_oop--;
142    _value--;
143    _size++;
144    _is_oop[0] = true;
145    _value[0] = (intptr_t)h.raw_value();
146  }
147
148  // Converts all Handles to oops, and returns a reference to parameter vector
149  intptr_t* parameters() ;
150  int   size_of_parameters() const { return _size; }
151
152  // Verify that pushed arguments fits a given method
153  void verify(methodHandle method, BasicType return_type, Thread *thread) PRODUCT_RETURN;
154};
155
156// All calls to Java have to go via JavaCalls. Sets up the stack frame
157// and makes sure that the last_Java_frame pointers are chained correctly.
158//
159
160class JavaCalls: AllStatic {
161  static void call_helper(JavaValue* result, methodHandle* method, JavaCallArguments* args, TRAPS);
162 public:
163  // Optimized Constuctor call
164  static void call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS);
165
166  // call_special
167  // ------------
168  // The receiver must be first oop in argument list
169  static void call_special(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS);
170
171  static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS); // No args
172  static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS);
173  static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS);
174
175  // virtual call
176  // ------------
177
178  // The receiver must be first oop in argument list
179  static void call_virtual(JavaValue* result, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS);
180
181  static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, TRAPS); // No args
182  static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS);
183  static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS);
184
185  // Static call
186  // -----------
187  static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, JavaCallArguments* args, TRAPS);
188
189  static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
190  static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, TRAPS);
191  static void call_static(JavaValue* result, KlassHandle klass, symbolHandle name, symbolHandle signature, Handle arg1, Handle arg2, TRAPS);
192
193  // Low-level interface
194  static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS);
195};
196