src/cpu/x86/vm/interpreterRT_x86_64.cpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4037
da91efe96a93
parent 0
f90c822e73f8
child 9448
73d689add964
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "interpreter/interpreter.hpp"
aoqi@0 27 #include "interpreter/interpreterRuntime.hpp"
aoqi@0 28 #include "memory/allocation.inline.hpp"
aoqi@0 29 #include "memory/universe.inline.hpp"
aoqi@0 30 #include "oops/method.hpp"
aoqi@0 31 #include "oops/oop.inline.hpp"
aoqi@0 32 #include "runtime/handles.inline.hpp"
aoqi@0 33 #include "runtime/icache.hpp"
aoqi@0 34 #include "runtime/interfaceSupport.hpp"
aoqi@0 35 #include "runtime/signature.hpp"
aoqi@0 36
aoqi@0 37 #define __ _masm->
aoqi@0 38
aoqi@0 39 // Implementation of SignatureHandlerGenerator
aoqi@0 40
aoqi@0 41 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
aoqi@0 42 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; }
aoqi@0 43 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
aoqi@0 44
aoqi@0 45 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
aoqi@0 46 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
aoqi@0 47
aoqi@0 48 #ifdef _WIN64
aoqi@0 49 switch (_num_args) {
aoqi@0 50 case 0:
aoqi@0 51 __ movl(c_rarg1, src);
aoqi@0 52 _num_args++;
aoqi@0 53 break;
aoqi@0 54 case 1:
aoqi@0 55 __ movl(c_rarg2, src);
aoqi@0 56 _num_args++;
aoqi@0 57 break;
aoqi@0 58 case 2:
aoqi@0 59 __ movl(c_rarg3, src);
aoqi@0 60 _num_args++;
aoqi@0 61 break;
aoqi@0 62 default:
aoqi@0 63 __ movl(rax, src);
aoqi@0 64 __ movl(Address(to(), _stack_offset), rax);
aoqi@0 65 _stack_offset += wordSize;
aoqi@0 66 break;
aoqi@0 67 }
aoqi@0 68 #else
aoqi@0 69 switch (_num_int_args) {
aoqi@0 70 case 0:
aoqi@0 71 __ movl(c_rarg1, src);
aoqi@0 72 _num_int_args++;
aoqi@0 73 break;
aoqi@0 74 case 1:
aoqi@0 75 __ movl(c_rarg2, src);
aoqi@0 76 _num_int_args++;
aoqi@0 77 break;
aoqi@0 78 case 2:
aoqi@0 79 __ movl(c_rarg3, src);
aoqi@0 80 _num_int_args++;
aoqi@0 81 break;
aoqi@0 82 case 3:
aoqi@0 83 __ movl(c_rarg4, src);
aoqi@0 84 _num_int_args++;
aoqi@0 85 break;
aoqi@0 86 case 4:
aoqi@0 87 __ movl(c_rarg5, src);
aoqi@0 88 _num_int_args++;
aoqi@0 89 break;
aoqi@0 90 default:
aoqi@0 91 __ movl(rax, src);
aoqi@0 92 __ movl(Address(to(), _stack_offset), rax);
aoqi@0 93 _stack_offset += wordSize;
aoqi@0 94 break;
aoqi@0 95 }
aoqi@0 96 #endif
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
aoqi@0 100 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
aoqi@0 101
aoqi@0 102 #ifdef _WIN64
aoqi@0 103 switch (_num_args) {
aoqi@0 104 case 0:
aoqi@0 105 __ movptr(c_rarg1, src);
aoqi@0 106 _num_args++;
aoqi@0 107 break;
aoqi@0 108 case 1:
aoqi@0 109 __ movptr(c_rarg2, src);
aoqi@0 110 _num_args++;
aoqi@0 111 break;
aoqi@0 112 case 2:
aoqi@0 113 __ movptr(c_rarg3, src);
aoqi@0 114 _num_args++;
aoqi@0 115 break;
aoqi@0 116 case 3:
aoqi@0 117 default:
aoqi@0 118 __ movptr(rax, src);
aoqi@0 119 __ movptr(Address(to(), _stack_offset), rax);
aoqi@0 120 _stack_offset += wordSize;
aoqi@0 121 break;
aoqi@0 122 }
aoqi@0 123 #else
aoqi@0 124 switch (_num_int_args) {
aoqi@0 125 case 0:
aoqi@0 126 __ movptr(c_rarg1, src);
aoqi@0 127 _num_int_args++;
aoqi@0 128 break;
aoqi@0 129 case 1:
aoqi@0 130 __ movptr(c_rarg2, src);
aoqi@0 131 _num_int_args++;
aoqi@0 132 break;
aoqi@0 133 case 2:
aoqi@0 134 __ movptr(c_rarg3, src);
aoqi@0 135 _num_int_args++;
aoqi@0 136 break;
aoqi@0 137 case 3:
aoqi@0 138 __ movptr(c_rarg4, src);
aoqi@0 139 _num_int_args++;
aoqi@0 140 break;
aoqi@0 141 case 4:
aoqi@0 142 __ movptr(c_rarg5, src);
aoqi@0 143 _num_int_args++;
aoqi@0 144 break;
aoqi@0 145 default:
aoqi@0 146 __ movptr(rax, src);
aoqi@0 147 __ movptr(Address(to(), _stack_offset), rax);
aoqi@0 148 _stack_offset += wordSize;
aoqi@0 149 break;
aoqi@0 150 }
aoqi@0 151 #endif
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
aoqi@0 155 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
aoqi@0 156
aoqi@0 157 #ifdef _WIN64
aoqi@0 158 if (_num_args < Argument::n_float_register_parameters_c-1) {
aoqi@0 159 __ movflt(as_XMMRegister(++_num_args), src);
aoqi@0 160 } else {
aoqi@0 161 __ movl(rax, src);
aoqi@0 162 __ movl(Address(to(), _stack_offset), rax);
aoqi@0 163 _stack_offset += wordSize;
aoqi@0 164 }
aoqi@0 165 #else
aoqi@0 166 if (_num_fp_args < Argument::n_float_register_parameters_c) {
aoqi@0 167 __ movflt(as_XMMRegister(_num_fp_args++), src);
aoqi@0 168 } else {
aoqi@0 169 __ movl(rax, src);
aoqi@0 170 __ movl(Address(to(), _stack_offset), rax);
aoqi@0 171 _stack_offset += wordSize;
aoqi@0 172 }
aoqi@0 173 #endif
aoqi@0 174 }
aoqi@0 175
aoqi@0 176 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
aoqi@0 177 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
aoqi@0 178
aoqi@0 179 #ifdef _WIN64
aoqi@0 180 if (_num_args < Argument::n_float_register_parameters_c-1) {
aoqi@0 181 __ movdbl(as_XMMRegister(++_num_args), src);
aoqi@0 182 } else {
aoqi@0 183 __ movptr(rax, src);
aoqi@0 184 __ movptr(Address(to(), _stack_offset), rax);
aoqi@0 185 _stack_offset += wordSize;
aoqi@0 186 }
aoqi@0 187 #else
aoqi@0 188 if (_num_fp_args < Argument::n_float_register_parameters_c) {
aoqi@0 189 __ movdbl(as_XMMRegister(_num_fp_args++), src);
aoqi@0 190 } else {
aoqi@0 191 __ movptr(rax, src);
aoqi@0 192 __ movptr(Address(to(), _stack_offset), rax);
aoqi@0 193 _stack_offset += wordSize;
aoqi@0 194 }
aoqi@0 195 #endif
aoqi@0 196 }
aoqi@0 197
aoqi@0 198 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
aoqi@0 199 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
aoqi@0 200
aoqi@0 201 #ifdef _WIN64
aoqi@0 202 switch (_num_args) {
aoqi@0 203 case 0:
aoqi@0 204 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
aoqi@0 205 __ lea(c_rarg1, src);
aoqi@0 206 _num_args++;
aoqi@0 207 break;
aoqi@0 208 case 1:
aoqi@0 209 __ lea(rax, src);
aoqi@0 210 __ xorl(c_rarg2, c_rarg2);
aoqi@0 211 __ cmpptr(src, 0);
aoqi@0 212 __ cmov(Assembler::notEqual, c_rarg2, rax);
aoqi@0 213 _num_args++;
aoqi@0 214 break;
aoqi@0 215 case 2:
aoqi@0 216 __ lea(rax, src);
aoqi@0 217 __ xorl(c_rarg3, c_rarg3);
aoqi@0 218 __ cmpptr(src, 0);
aoqi@0 219 __ cmov(Assembler::notEqual, c_rarg3, rax);
aoqi@0 220 _num_args++;
aoqi@0 221 break;
aoqi@0 222 default:
aoqi@0 223 __ lea(rax, src);
aoqi@0 224 __ xorl(temp(), temp());
aoqi@0 225 __ cmpptr(src, 0);
aoqi@0 226 __ cmov(Assembler::notEqual, temp(), rax);
aoqi@0 227 __ movptr(Address(to(), _stack_offset), temp());
aoqi@0 228 _stack_offset += wordSize;
aoqi@0 229 break;
aoqi@0 230 }
aoqi@0 231 #else
aoqi@0 232 switch (_num_int_args) {
aoqi@0 233 case 0:
aoqi@0 234 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
aoqi@0 235 __ lea(c_rarg1, src);
aoqi@0 236 _num_int_args++;
aoqi@0 237 break;
aoqi@0 238 case 1:
aoqi@0 239 __ lea(rax, src);
aoqi@0 240 __ xorl(c_rarg2, c_rarg2);
aoqi@0 241 __ cmpptr(src, 0);
aoqi@0 242 __ cmov(Assembler::notEqual, c_rarg2, rax);
aoqi@0 243 _num_int_args++;
aoqi@0 244 break;
aoqi@0 245 case 2:
aoqi@0 246 __ lea(rax, src);
aoqi@0 247 __ xorl(c_rarg3, c_rarg3);
aoqi@0 248 __ cmpptr(src, 0);
aoqi@0 249 __ cmov(Assembler::notEqual, c_rarg3, rax);
aoqi@0 250 _num_int_args++;
aoqi@0 251 break;
aoqi@0 252 case 3:
aoqi@0 253 __ lea(rax, src);
aoqi@0 254 __ xorl(c_rarg4, c_rarg4);
aoqi@0 255 __ cmpptr(src, 0);
aoqi@0 256 __ cmov(Assembler::notEqual, c_rarg4, rax);
aoqi@0 257 _num_int_args++;
aoqi@0 258 break;
aoqi@0 259 case 4:
aoqi@0 260 __ lea(rax, src);
aoqi@0 261 __ xorl(c_rarg5, c_rarg5);
aoqi@0 262 __ cmpptr(src, 0);
aoqi@0 263 __ cmov(Assembler::notEqual, c_rarg5, rax);
aoqi@0 264 _num_int_args++;
aoqi@0 265 break;
aoqi@0 266 default:
aoqi@0 267 __ lea(rax, src);
aoqi@0 268 __ xorl(temp(), temp());
aoqi@0 269 __ cmpptr(src, 0);
aoqi@0 270 __ cmov(Assembler::notEqual, temp(), rax);
aoqi@0 271 __ movptr(Address(to(), _stack_offset), temp());
aoqi@0 272 _stack_offset += wordSize;
aoqi@0 273 break;
aoqi@0 274 }
aoqi@0 275 #endif
aoqi@0 276 }
aoqi@0 277
aoqi@0 278 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
aoqi@0 279 // generate code to handle arguments
aoqi@0 280 iterate(fingerprint);
aoqi@0 281
aoqi@0 282 // return result handler
aoqi@0 283 __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));
aoqi@0 284 __ ret(0);
aoqi@0 285
aoqi@0 286 __ flush();
aoqi@0 287 }
aoqi@0 288
aoqi@0 289
aoqi@0 290 // Implementation of SignatureHandlerLibrary
aoqi@0 291
aoqi@0 292 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
aoqi@0 293
aoqi@0 294
aoqi@0 295 #ifdef _WIN64
aoqi@0 296 class SlowSignatureHandler
aoqi@0 297 : public NativeSignatureIterator {
aoqi@0 298 private:
aoqi@0 299 address _from;
aoqi@0 300 intptr_t* _to;
aoqi@0 301 intptr_t* _reg_args;
aoqi@0 302 intptr_t* _fp_identifiers;
aoqi@0 303 unsigned int _num_args;
aoqi@0 304
aoqi@0 305 virtual void pass_int()
aoqi@0 306 {
aoqi@0 307 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
aoqi@0 308 _from -= Interpreter::stackElementSize;
aoqi@0 309
aoqi@0 310 if (_num_args < Argument::n_int_register_parameters_c-1) {
aoqi@0 311 *_reg_args++ = from_obj;
aoqi@0 312 _num_args++;
aoqi@0 313 } else {
aoqi@0 314 *_to++ = from_obj;
aoqi@0 315 }
aoqi@0 316 }
aoqi@0 317
aoqi@0 318 virtual void pass_long()
aoqi@0 319 {
aoqi@0 320 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
aoqi@0 321 _from -= 2*Interpreter::stackElementSize;
aoqi@0 322
aoqi@0 323 if (_num_args < Argument::n_int_register_parameters_c-1) {
aoqi@0 324 *_reg_args++ = from_obj;
aoqi@0 325 _num_args++;
aoqi@0 326 } else {
aoqi@0 327 *_to++ = from_obj;
aoqi@0 328 }
aoqi@0 329 }
aoqi@0 330
aoqi@0 331 virtual void pass_object()
aoqi@0 332 {
aoqi@0 333 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
aoqi@0 334 _from -= Interpreter::stackElementSize;
aoqi@0 335 if (_num_args < Argument::n_int_register_parameters_c-1) {
aoqi@0 336 *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
aoqi@0 337 _num_args++;
aoqi@0 338 } else {
aoqi@0 339 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
aoqi@0 340 }
aoqi@0 341 }
aoqi@0 342
aoqi@0 343 virtual void pass_float()
aoqi@0 344 {
aoqi@0 345 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
aoqi@0 346 _from -= Interpreter::stackElementSize;
aoqi@0 347
aoqi@0 348 if (_num_args < Argument::n_float_register_parameters_c-1) {
aoqi@0 349 *_reg_args++ = from_obj;
aoqi@0 350 *_fp_identifiers |= (intptr_t)(0x01 << (_num_args*2)); // mark as float
aoqi@0 351 _num_args++;
aoqi@0 352 } else {
aoqi@0 353 *_to++ = from_obj;
aoqi@0 354 }
aoqi@0 355 }
aoqi@0 356
aoqi@0 357 virtual void pass_double()
aoqi@0 358 {
aoqi@0 359 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
aoqi@0 360 _from -= 2*Interpreter::stackElementSize;
aoqi@0 361
aoqi@0 362 if (_num_args < Argument::n_float_register_parameters_c-1) {
aoqi@0 363 *_reg_args++ = from_obj;
aoqi@0 364 *_fp_identifiers |= (intptr_t)(0x3 << (_num_args*2)); // mark as double
aoqi@0 365 _num_args++;
aoqi@0 366 } else {
aoqi@0 367 *_to++ = from_obj;
aoqi@0 368 }
aoqi@0 369 }
aoqi@0 370
aoqi@0 371 public:
aoqi@0 372 SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
aoqi@0 373 : NativeSignatureIterator(method)
aoqi@0 374 {
aoqi@0 375 _from = from;
aoqi@0 376 _to = to;
aoqi@0 377
aoqi@0 378 _reg_args = to - (method->is_static() ? 4 : 5);
aoqi@0 379 _fp_identifiers = to - 2;
aoqi@0 380 _to = _to + 4; // Windows reserves stack space for register arguments
aoqi@0 381 *(int*) _fp_identifiers = 0;
aoqi@0 382 _num_args = (method->is_static() ? 1 : 0);
aoqi@0 383 }
aoqi@0 384 };
aoqi@0 385 #else
aoqi@0 386 class SlowSignatureHandler
aoqi@0 387 : public NativeSignatureIterator {
aoqi@0 388 private:
aoqi@0 389 address _from;
aoqi@0 390 intptr_t* _to;
aoqi@0 391 intptr_t* _int_args;
aoqi@0 392 intptr_t* _fp_args;
aoqi@0 393 intptr_t* _fp_identifiers;
aoqi@0 394 unsigned int _num_int_args;
aoqi@0 395 unsigned int _num_fp_args;
aoqi@0 396
aoqi@0 397 virtual void pass_int()
aoqi@0 398 {
aoqi@0 399 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
aoqi@0 400 _from -= Interpreter::stackElementSize;
aoqi@0 401
aoqi@0 402 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
aoqi@0 403 *_int_args++ = from_obj;
aoqi@0 404 _num_int_args++;
aoqi@0 405 } else {
aoqi@0 406 *_to++ = from_obj;
aoqi@0 407 }
aoqi@0 408 }
aoqi@0 409
aoqi@0 410 virtual void pass_long()
aoqi@0 411 {
aoqi@0 412 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
aoqi@0 413 _from -= 2*Interpreter::stackElementSize;
aoqi@0 414
aoqi@0 415 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
aoqi@0 416 *_int_args++ = from_obj;
aoqi@0 417 _num_int_args++;
aoqi@0 418 } else {
aoqi@0 419 *_to++ = from_obj;
aoqi@0 420 }
aoqi@0 421 }
aoqi@0 422
aoqi@0 423 virtual void pass_object()
aoqi@0 424 {
aoqi@0 425 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
aoqi@0 426 _from -= Interpreter::stackElementSize;
aoqi@0 427
aoqi@0 428 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
aoqi@0 429 *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
aoqi@0 430 _num_int_args++;
aoqi@0 431 } else {
aoqi@0 432 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
aoqi@0 433 }
aoqi@0 434 }
aoqi@0 435
aoqi@0 436 virtual void pass_float()
aoqi@0 437 {
aoqi@0 438 jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
aoqi@0 439 _from -= Interpreter::stackElementSize;
aoqi@0 440
aoqi@0 441 if (_num_fp_args < Argument::n_float_register_parameters_c) {
aoqi@0 442 *_fp_args++ = from_obj;
aoqi@0 443 _num_fp_args++;
aoqi@0 444 } else {
aoqi@0 445 *_to++ = from_obj;
aoqi@0 446 }
aoqi@0 447 }
aoqi@0 448
aoqi@0 449 virtual void pass_double()
aoqi@0 450 {
aoqi@0 451 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
aoqi@0 452 _from -= 2*Interpreter::stackElementSize;
aoqi@0 453
aoqi@0 454 if (_num_fp_args < Argument::n_float_register_parameters_c) {
aoqi@0 455 *_fp_args++ = from_obj;
aoqi@0 456 *_fp_identifiers |= (1 << _num_fp_args); // mark as double
aoqi@0 457 _num_fp_args++;
aoqi@0 458 } else {
aoqi@0 459 *_to++ = from_obj;
aoqi@0 460 }
aoqi@0 461 }
aoqi@0 462
aoqi@0 463 public:
aoqi@0 464 SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
aoqi@0 465 : NativeSignatureIterator(method)
aoqi@0 466 {
aoqi@0 467 _from = from;
aoqi@0 468 _to = to;
aoqi@0 469
aoqi@0 470 _int_args = to - (method->is_static() ? 14 : 15);
aoqi@0 471 _fp_args = to - 9;
aoqi@0 472 _fp_identifiers = to - 10;
aoqi@0 473 *(int*) _fp_identifiers = 0;
aoqi@0 474 _num_int_args = (method->is_static() ? 1 : 0);
aoqi@0 475 _num_fp_args = 0;
aoqi@0 476 }
aoqi@0 477 };
aoqi@0 478 #endif
aoqi@0 479
aoqi@0 480
aoqi@0 481 IRT_ENTRY(address,
aoqi@0 482 InterpreterRuntime::slow_signature_handler(JavaThread* thread,
aoqi@0 483 Method* method,
aoqi@0 484 intptr_t* from,
aoqi@0 485 intptr_t* to))
aoqi@0 486 methodHandle m(thread, (Method*)method);
aoqi@0 487 assert(m->is_native(), "sanity check");
aoqi@0 488
aoqi@0 489 // handle arguments
aoqi@0 490 SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
aoqi@0 491
aoqi@0 492 // return result handler
aoqi@0 493 return Interpreter::result_handler(m->result_type());
aoqi@0 494 IRT_END

mercurial