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 } |