src/share/vm/runtime/javaCalls.cpp

changeset 9669
32bc598624bd
parent 8739
0b85ccd62409
child 9703
2fdf635bcf28
equal deleted inserted replaced
9668:acb9351e3a29 9669:32bc598624bd
1 /* 1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
323 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) 323 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
324 324
325 // Verify the arguments 325 // Verify the arguments
326 326
327 if (CheckJNICalls) { 327 if (CheckJNICalls) {
328 args->verify(method, result->get_type(), thread); 328 args->verify(method, result->get_type());
329 } 329 }
330 else debug_only(args->verify(method, result->get_type(), thread)); 330 else debug_only(args->verify(method, result->get_type()));
331 331
332 // Ignore call if method is empty 332 // Ignore call if method is empty
333 if (method->is_empty_method()) { 333 if (method->is_empty_method()) {
334 assert(result->get_type() == T_VOID, "an empty method must return a void value"); 334 assert(result->get_type() == T_VOID, "an empty method must return a void value");
335 return; 335 return;
427 427
428 428
429 //-------------------------------------------------------------------------------------- 429 //--------------------------------------------------------------------------------------
430 // Implementation of JavaCallArguments 430 // Implementation of JavaCallArguments
431 431
432 inline bool is_value_state_indirect_oop(uint state) {
433 assert(state != JavaCallArguments::value_state_oop,
434 "Checking for handles after removal");
435 assert(state < JavaCallArguments::value_state_limit, "Invalid value state");
436 return state != JavaCallArguments::value_state_primitive;
437 }
438
439 inline oop resolve_indirect_oop(intptr_t value, uint state) {
440 switch (state) {
441 case JavaCallArguments::value_state_handle:
442 {
443 oop* ptr = reinterpret_cast<oop*>(value);
444 return Handle::raw_resolve(ptr);
445 }
446
447 case JavaCallArguments::value_state_jobject:
448 {
449 jobject obj = reinterpret_cast<jobject>(value);
450 return JNIHandles::resolve(obj);
451 }
452
453 default:
454 ShouldNotReachHere();
455 return NULL;
456 }
457 }
458
432 intptr_t* JavaCallArguments::parameters() { 459 intptr_t* JavaCallArguments::parameters() {
433 // First convert all handles to oops 460 // First convert all handles to oops
434 for(int i = 0; i < _size; i++) { 461 for(int i = 0; i < _size; i++) {
435 if (_is_oop[i]) { 462 uint state = _value_state[i];
436 // Handle conversion 463 assert(state != value_state_oop, "Multiple handle conversions");
437 _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i])); 464 if (is_value_state_indirect_oop(state)) {
465 oop obj = resolve_indirect_oop(_value[i], state);
466 _value[i] = cast_from_oop<intptr_t>(obj);
467 _value_state[i] = value_state_oop;
438 } 468 }
439 } 469 }
440 // Return argument vector 470 // Return argument vector
441 return _value; 471 return _value;
442 } 472 }
443 473
444 474
445 class SignatureChekker : public SignatureIterator { 475 class SignatureChekker : public SignatureIterator {
446 private: 476 private:
447 bool *_is_oop; 477 int _pos;
448 int _pos; 478 BasicType _return_type;
449 BasicType _return_type; 479 u_char* _value_state;
450 intptr_t* _value; 480 intptr_t* _value;
451 Thread* _thread;
452 481
453 public: 482 public:
454 bool _is_return; 483 bool _is_return;
455 484
456 SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { 485 SignatureChekker(Symbol* signature,
457 _is_oop = is_oop; 486 BasicType return_type,
458 _is_return = false; 487 bool is_static,
459 _return_type = return_type; 488 u_char* value_state,
460 _pos = 0; 489 intptr_t* value) :
461 _value = value; 490 SignatureIterator(signature),
462 _thread = thread; 491 _pos(0),
463 492 _return_type(return_type),
493 _value_state(value_state),
494 _value(value),
495 _is_return(false)
496 {
464 if (!is_static) { 497 if (!is_static) {
465 check_value(true); // Receiver must be an oop 498 check_value(true); // Receiver must be an oop
466 } 499 }
467 } 500 }
468 501
469 void check_value(bool type) { 502 void check_value(bool type) {
470 guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); 503 uint state = _value_state[_pos++];
504 if (type) {
505 guarantee(is_value_state_indirect_oop(state),
506 "signature does not match pushed arguments");
507 } else {
508 guarantee(state == JavaCallArguments::value_state_primitive,
509 "signature does not match pushed arguments");
510 }
471 } 511 }
472 512
473 void check_doing_return(bool state) { _is_return = state; } 513 void check_doing_return(bool state) { _is_return = state; }
474 514
475 void check_return_type(BasicType t) { 515 void check_return_type(BasicType t) {
500 if (_is_return) { 540 if (_is_return) {
501 check_return_type(t); 541 check_return_type(t);
502 return; 542 return;
503 } 543 }
504 544
505 // verify handle and the oop pointed to by handle 545 intptr_t v = _value[_pos];
506 int p = _pos; 546 if (v != 0) {
507 bool bad = false; 547 // v is a "handle" referring to an oop, cast to integral type.
508 // If argument is oop 548 // There shouldn't be any handles in very low memory.
509 if (_is_oop[p]) { 549 guarantee((size_t)v >= (size_t)os::vm_page_size(),
510 intptr_t v = _value[p]; 550 "Bad JNI oop argument");
511 if (v != 0 ) { 551 // Verify the pointee.
512 size_t t = (size_t)v; 552 oop vv = resolve_indirect_oop(v, _value_state[_pos]);
513 bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true); 553 guarantee(vv->is_oop_or_null(true),
514 if (CheckJNICalls && bad) { 554 "Bad JNI oop argument");
515 ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); 555 }
516 } 556
517 } 557 check_value(true); // Verify value state.
518 // for the regular debug case.
519 assert(!bad, "Bad JNI oop argument");
520 }
521
522 check_value(true);
523 } 558 }
524 559
525 void do_bool() { check_int(T_BOOLEAN); } 560 void do_bool() { check_int(T_BOOLEAN); }
526 void do_char() { check_int(T_CHAR); } 561 void do_char() { check_int(T_CHAR); }
527 void do_float() { check_int(T_FLOAT); } 562 void do_float() { check_int(T_FLOAT); }
534 void do_object(int begin, int end) { check_obj(T_OBJECT); } 569 void do_object(int begin, int end) { check_obj(T_OBJECT); }
535 void do_array(int begin, int end) { check_obj(T_OBJECT); } 570 void do_array(int begin, int end) { check_obj(T_OBJECT); }
536 }; 571 };
537 572
538 573
539 void JavaCallArguments::verify(methodHandle method, BasicType return_type, 574 void JavaCallArguments::verify(methodHandle method, BasicType return_type) {
540 Thread *thread) {
541 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); 575 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
542 576
543 // Treat T_OBJECT and T_ARRAY as the same 577 // Treat T_OBJECT and T_ARRAY as the same
544 if (return_type == T_ARRAY) return_type = T_OBJECT; 578 if (return_type == T_ARRAY) return_type = T_OBJECT;
545 579
546 // Check that oop information is correct 580 // Check that oop information is correct
547 Symbol* signature = method->signature(); 581 Symbol* signature = method->signature();
548 582
549 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); 583 SignatureChekker sc(signature,
584 return_type,
585 method->is_static(),
586 _value_state,
587 _value);
550 sc.iterate_parameters(); 588 sc.iterate_parameters();
551 sc.check_doing_return(true); 589 sc.check_doing_return(true);
552 sc.iterate_returntype(); 590 sc.iterate_returntype();
553 } 591 }

mercurial