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