hotspot/src/share/vm/runtime/javaCalls.cpp
changeset 44406 a46a6c4d1dd9
parent 44093 e22e0d071bf9
child 44738 11431bbc9549
child 46369 3bf4544bec14
equal deleted inserted replaced
44405:5bc48f22b149 44406:a46a6c4d1dd9
     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.
   326   if (alternative_target == NULL) {
   326   if (alternative_target == NULL) {
   327 #endif
   327 #endif
   328 // Verify the arguments
   328 // Verify the arguments
   329 
   329 
   330   if (CheckJNICalls)  {
   330   if (CheckJNICalls)  {
   331     args->verify(method, result->get_type(), thread);
   331     args->verify(method, result->get_type());
   332   }
   332   }
   333   else debug_only(args->verify(method, result->get_type(), thread));
   333   else debug_only(args->verify(method, result->get_type()));
   334 #if INCLUDE_JVMCI
   334 #if INCLUDE_JVMCI
   335   }
   335   }
   336 #else
   336 #else
   337 
   337 
   338   // Ignore call if method is empty
   338   // Ignore call if method is empty
   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 }