interpreterRT_zero.cpp revision 1010:354d3184f6b2
1/*
2 * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
3 * Copyright 2007, 2008 Red Hat, Inc.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 *
24 */
25
26#include "incls/_precompiled.incl"
27#include "incls/_interpreterRT_zero.cpp.incl"
28
29void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_int() {
30  push(T_INT);
31  _cif->nargs++;
32}
33
34void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_long() {
35  push(T_LONG);
36  _cif->nargs++;
37}
38
39void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_float() {
40  push(T_FLOAT);
41  _cif->nargs++;
42}
43
44void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_double() {
45  push(T_DOUBLE);
46  _cif->nargs++;
47}
48
49void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_object() {
50  push(T_OBJECT);
51  _cif->nargs++;
52}
53
54void InterpreterRuntime::SignatureHandlerGeneratorBase::push(BasicType type) {
55  ffi_type *ftype;
56  switch (type) {
57  case T_VOID:
58    ftype = &ffi_type_void;
59    break;
60
61  case T_BOOLEAN:
62    ftype = &ffi_type_uint8;
63    break;
64
65  case T_CHAR:
66    ftype = &ffi_type_uint16;
67    break;
68
69  case T_BYTE:
70    ftype = &ffi_type_sint8;
71    break;
72
73  case T_SHORT:
74    ftype = &ffi_type_sint16;
75    break;
76
77  case T_INT:
78    ftype = &ffi_type_sint32;
79    break;
80
81  case T_LONG:
82    ftype = &ffi_type_sint64;
83    break;
84
85  case T_FLOAT:
86    ftype = &ffi_type_float;
87    break;
88
89  case T_DOUBLE:
90    ftype = &ffi_type_double;
91    break;
92
93  case T_OBJECT:
94  case T_ARRAY:
95    ftype = &ffi_type_pointer;
96    break;
97
98  default:
99    ShouldNotReachHere();
100  }
101  push((intptr_t) ftype);
102}
103
104// For fast signature handlers the "signature handler" is generated
105// into a temporary buffer.  It is then copied to its final location,
106// and pd_set_handler is called on it.  We have this two stage thing
107// to accomodate this.
108
109void InterpreterRuntime::SignatureHandlerGeneratorBase::generate(
110  uint64_t fingerprint) {
111
112  // Build the argument types list
113  pass_object();
114  if (method()->is_static())
115    pass_object();
116  iterate(fingerprint);
117
118  // Tack on the result type
119  push(method()->result_type());
120}
121
122void InterpreterRuntime::SignatureHandler::finalize() {
123  ffi_status status =
124    ffi_prep_cif(cif(),
125                 FFI_DEFAULT_ABI,
126                 argument_count(),
127                 result_type(),
128                 argument_types());
129
130  assert(status == FFI_OK, "should be");
131}
132
133IRT_ENTRY(address,
134          InterpreterRuntime::slow_signature_handler(JavaThread* thread,
135                                                     methodOop   method,
136                                                     intptr_t*   unused1,
137                                                     intptr_t*   unused2))
138  ZeroStack *stack = thread->zero_stack();
139
140  int required_words =
141    (align_size_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) +
142    (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1;
143  if (required_words > stack->available_words()) {
144    Unimplemented();
145  }
146
147  intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize);
148  SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf);
149  sshg.generate(UCONST64(-1));
150
151  SignatureHandler *handler = sshg.handler();
152  handler->finalize();
153
154  return (address) handler;
155IRT_END
156
157void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) {
158  InterpreterRuntime::SignatureHandler *handler =
159    InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
160
161  handler->finalize();
162}
163