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. |
440 |
440 |
441 |
441 |
442 //-------------------------------------------------------------------------------------- |
442 //-------------------------------------------------------------------------------------- |
443 // Implementation of JavaCallArguments |
443 // Implementation of JavaCallArguments |
444 |
444 |
|
445 inline bool is_value_state_indirect_oop(uint state) { |
|
446 assert(state != JavaCallArguments::value_state_oop, |
|
447 "Checking for handles after removal"); |
|
448 assert(state < JavaCallArguments::value_state_limit, |
|
449 "Invalid value state %u", state); |
|
450 return state != JavaCallArguments::value_state_primitive; |
|
451 } |
|
452 |
|
453 inline oop resolve_indirect_oop(intptr_t value, uint state) { |
|
454 switch (state) { |
|
455 case JavaCallArguments::value_state_handle: |
|
456 { |
|
457 oop* ptr = reinterpret_cast<oop*>(value); |
|
458 return Handle::raw_resolve(ptr); |
|
459 } |
|
460 |
|
461 case JavaCallArguments::value_state_jobject: |
|
462 { |
|
463 jobject obj = reinterpret_cast<jobject>(value); |
|
464 return JNIHandles::resolve(obj); |
|
465 } |
|
466 |
|
467 default: |
|
468 ShouldNotReachHere(); |
|
469 return NULL; |
|
470 } |
|
471 } |
|
472 |
445 intptr_t* JavaCallArguments::parameters() { |
473 intptr_t* JavaCallArguments::parameters() { |
446 // First convert all handles to oops |
474 // First convert all handles to oops |
447 for(int i = 0; i < _size; i++) { |
475 for(int i = 0; i < _size; i++) { |
448 if (_is_oop[i]) { |
476 uint state = _value_state[i]; |
449 // Handle conversion |
477 assert(state != value_state_oop, "Multiple handle conversions"); |
450 _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i])); |
478 if (is_value_state_indirect_oop(state)) { |
|
479 oop obj = resolve_indirect_oop(_value[i], state); |
|
480 _value[i] = cast_from_oop<intptr_t>(obj); |
|
481 _value_state[i] = value_state_oop; |
451 } |
482 } |
452 } |
483 } |
453 // Return argument vector |
484 // Return argument vector |
454 return _value; |
485 return _value; |
455 } |
486 } |
456 |
487 |
457 |
488 |
458 class SignatureChekker : public SignatureIterator { |
489 class SignatureChekker : public SignatureIterator { |
459 private: |
490 private: |
460 bool *_is_oop; |
491 int _pos; |
461 int _pos; |
|
462 BasicType _return_type; |
492 BasicType _return_type; |
463 intptr_t* _value; |
493 u_char* _value_state; |
464 Thread* _thread; |
494 intptr_t* _value; |
465 |
495 |
466 public: |
496 public: |
467 bool _is_return; |
497 bool _is_return; |
468 |
498 |
469 SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { |
499 SignatureChekker(Symbol* signature, |
470 _is_oop = is_oop; |
500 BasicType return_type, |
471 _is_return = false; |
501 bool is_static, |
472 _return_type = return_type; |
502 u_char* value_state, |
473 _pos = 0; |
503 intptr_t* value) : |
474 _value = value; |
504 SignatureIterator(signature), |
475 _thread = thread; |
505 _pos(0), |
476 |
506 _return_type(return_type), |
|
507 _value_state(value_state), |
|
508 _value(value), |
|
509 _is_return(false) |
|
510 { |
477 if (!is_static) { |
511 if (!is_static) { |
478 check_value(true); // Receiver must be an oop |
512 check_value(true); // Receiver must be an oop |
479 } |
513 } |
480 } |
514 } |
481 |
515 |
482 void check_value(bool type) { |
516 void check_value(bool type) { |
483 guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); |
517 uint state = _value_state[_pos++]; |
|
518 if (type) { |
|
519 guarantee(is_value_state_indirect_oop(state), |
|
520 "signature does not match pushed arguments: %u at %d", |
|
521 state, _pos - 1); |
|
522 } else { |
|
523 guarantee(state == JavaCallArguments::value_state_primitive, |
|
524 "signature does not match pushed arguments: %u at %d", |
|
525 state, _pos - 1); |
|
526 } |
484 } |
527 } |
485 |
528 |
486 void check_doing_return(bool state) { _is_return = state; } |
529 void check_doing_return(bool state) { _is_return = state; } |
487 |
530 |
488 void check_return_type(BasicType t) { |
531 void check_return_type(BasicType t) { |
513 if (_is_return) { |
556 if (_is_return) { |
514 check_return_type(t); |
557 check_return_type(t); |
515 return; |
558 return; |
516 } |
559 } |
517 |
560 |
518 // verify handle and the oop pointed to by handle |
561 intptr_t v = _value[_pos]; |
519 int p = _pos; |
562 if (v != 0) { |
520 bool bad = false; |
563 // v is a "handle" referring to an oop, cast to integral type. |
521 // If argument is oop |
564 // There shouldn't be any handles in very low memory. |
522 if (_is_oop[p]) { |
565 guarantee((size_t)v >= (size_t)os::vm_page_size(), |
523 intptr_t v = _value[p]; |
566 "Bad JNI oop argument %d: " PTR_FORMAT, _pos, v); |
524 if (v != 0 ) { |
567 // Verify the pointee. |
525 size_t t = (size_t)v; |
568 oop vv = resolve_indirect_oop(v, _value_state[_pos]); |
526 bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true); |
569 guarantee(vv->is_oop_or_null(true), |
527 if (CheckJNICalls && bad) { |
570 "Bad JNI oop argument %d: " PTR_FORMAT " -> " PTR_FORMAT, |
528 ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); |
571 _pos, v, p2i(vv)); |
529 } |
572 } |
530 } |
573 |
531 // for the regular debug case. |
574 check_value(true); // Verify value state. |
532 assert(!bad, "Bad JNI oop argument"); |
|
533 } |
|
534 |
|
535 check_value(true); |
|
536 } |
575 } |
537 |
576 |
538 void do_bool() { check_int(T_BOOLEAN); } |
577 void do_bool() { check_int(T_BOOLEAN); } |
539 void do_char() { check_int(T_CHAR); } |
578 void do_char() { check_int(T_CHAR); } |
540 void do_float() { check_int(T_FLOAT); } |
579 void do_float() { check_int(T_FLOAT); } |
547 void do_object(int begin, int end) { check_obj(T_OBJECT); } |
586 void do_object(int begin, int end) { check_obj(T_OBJECT); } |
548 void do_array(int begin, int end) { check_obj(T_OBJECT); } |
587 void do_array(int begin, int end) { check_obj(T_OBJECT); } |
549 }; |
588 }; |
550 |
589 |
551 |
590 |
552 void JavaCallArguments::verify(const methodHandle& method, BasicType return_type, |
591 void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) { |
553 Thread *thread) { |
|
554 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); |
592 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); |
555 |
593 |
556 // Treat T_OBJECT and T_ARRAY as the same |
594 // Treat T_OBJECT and T_ARRAY as the same |
557 if (return_type == T_ARRAY) return_type = T_OBJECT; |
595 if (return_type == T_ARRAY) return_type = T_OBJECT; |
558 |
596 |
559 // Check that oop information is correct |
597 // Check that oop information is correct |
560 Symbol* signature = method->signature(); |
598 Symbol* signature = method->signature(); |
561 |
599 |
562 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); |
600 SignatureChekker sc(signature, |
|
601 return_type, |
|
602 method->is_static(), |
|
603 _value_state, |
|
604 _value); |
563 sc.iterate_parameters(); |
605 sc.iterate_parameters(); |
564 sc.check_doing_return(true); |
606 sc.check_doing_return(true); |
565 sc.iterate_returntype(); |
607 sc.iterate_returntype(); |
566 } |
608 } |