src/share/vm/runtime/javaCalls.cpp

changeset 9703
2fdf635bcf28
parent 8856
ac27a9c85bea
parent 9669
32bc598624bd
     1.1 --- a/src/share/vm/runtime/javaCalls.cpp	Thu Sep 05 18:40:52 2019 +0800
     1.2 +++ b/src/share/vm/runtime/javaCalls.cpp	Thu Sep 05 18:52:27 2019 +0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -325,9 +325,9 @@
    1.11    // Verify the arguments
    1.12  
    1.13    if (CheckJNICalls)  {
    1.14 -    args->verify(method, result->get_type(), thread);
    1.15 +    args->verify(method, result->get_type());
    1.16    }
    1.17 -  else debug_only(args->verify(method, result->get_type(), thread));
    1.18 +  else debug_only(args->verify(method, result->get_type()));
    1.19  
    1.20    // Ignore call if method is empty
    1.21    if (method->is_empty_method()) {
    1.22 @@ -429,12 +429,42 @@
    1.23  //--------------------------------------------------------------------------------------
    1.24  // Implementation of JavaCallArguments
    1.25  
    1.26 +inline bool is_value_state_indirect_oop(uint state) {
    1.27 +  assert(state != JavaCallArguments::value_state_oop,
    1.28 +         "Checking for handles after removal");
    1.29 +  assert(state < JavaCallArguments::value_state_limit, "Invalid value state");
    1.30 +  return state != JavaCallArguments::value_state_primitive;
    1.31 +}
    1.32 +
    1.33 +inline oop resolve_indirect_oop(intptr_t value, uint state) {
    1.34 +  switch (state) {
    1.35 +  case JavaCallArguments::value_state_handle:
    1.36 +  {
    1.37 +    oop* ptr = reinterpret_cast<oop*>(value);
    1.38 +    return Handle::raw_resolve(ptr);
    1.39 +  }
    1.40 +
    1.41 +  case JavaCallArguments::value_state_jobject:
    1.42 +  {
    1.43 +    jobject obj = reinterpret_cast<jobject>(value);
    1.44 +    return JNIHandles::resolve(obj);
    1.45 +  }
    1.46 +
    1.47 +  default:
    1.48 +    ShouldNotReachHere();
    1.49 +    return NULL;
    1.50 +  }
    1.51 +}
    1.52 +
    1.53  intptr_t* JavaCallArguments::parameters() {
    1.54    // First convert all handles to oops
    1.55    for(int i = 0; i < _size; i++) {
    1.56 -    if (_is_oop[i]) {
    1.57 -      // Handle conversion
    1.58 -      _value[i] = cast_from_oop<intptr_t>(Handle::raw_resolve((oop *)_value[i]));
    1.59 +    uint state = _value_state[i];
    1.60 +    assert(state != value_state_oop, "Multiple handle conversions");
    1.61 +    if (is_value_state_indirect_oop(state)) {
    1.62 +      oop obj = resolve_indirect_oop(_value[i], state);
    1.63 +      _value[i] = cast_from_oop<intptr_t>(obj);
    1.64 +      _value_state[i] = value_state_oop;
    1.65      }
    1.66    }
    1.67    // Return argument vector
    1.68 @@ -444,30 +474,40 @@
    1.69  
    1.70  class SignatureChekker : public SignatureIterator {
    1.71   private:
    1.72 -   bool *_is_oop;
    1.73 -   int   _pos;
    1.74 -   BasicType _return_type;
    1.75 -   intptr_t*   _value;
    1.76 -   Thread* _thread;
    1.77 +  int _pos;
    1.78 +  BasicType _return_type;
    1.79 +  u_char* _value_state;
    1.80 +  intptr_t* _value;
    1.81  
    1.82   public:
    1.83    bool _is_return;
    1.84  
    1.85 -  SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
    1.86 -    _is_oop = is_oop;
    1.87 -    _is_return = false;
    1.88 -    _return_type = return_type;
    1.89 -    _pos = 0;
    1.90 -    _value = value;
    1.91 -    _thread = thread;
    1.92 -
    1.93 +  SignatureChekker(Symbol* signature,
    1.94 +                   BasicType return_type,
    1.95 +                   bool is_static,
    1.96 +                   u_char* value_state,
    1.97 +                   intptr_t* value) :
    1.98 +    SignatureIterator(signature),
    1.99 +    _pos(0),
   1.100 +    _return_type(return_type),
   1.101 +    _value_state(value_state),
   1.102 +    _value(value),
   1.103 +    _is_return(false)
   1.104 +  {
   1.105      if (!is_static) {
   1.106        check_value(true); // Receiver must be an oop
   1.107      }
   1.108    }
   1.109  
   1.110    void check_value(bool type) {
   1.111 -    guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments");
   1.112 +    uint state = _value_state[_pos++];
   1.113 +    if (type) {
   1.114 +      guarantee(is_value_state_indirect_oop(state),
   1.115 +                "signature does not match pushed arguments");
   1.116 +    } else {
   1.117 +      guarantee(state == JavaCallArguments::value_state_primitive,
   1.118 +                "signature does not match pushed arguments");
   1.119 +    }
   1.120    }
   1.121  
   1.122    void check_doing_return(bool state) { _is_return = state; }
   1.123 @@ -502,24 +542,19 @@
   1.124        return;
   1.125      }
   1.126  
   1.127 -    // verify handle and the oop pointed to by handle
   1.128 -    int p = _pos;
   1.129 -    bool bad = false;
   1.130 -    // If argument is oop
   1.131 -    if (_is_oop[p]) {
   1.132 -      intptr_t v = _value[p];
   1.133 -      if (v != 0 ) {
   1.134 -        size_t t = (size_t)v;
   1.135 -        bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
   1.136 -        if (CheckJNICalls && bad) {
   1.137 -          ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
   1.138 -        }
   1.139 -      }
   1.140 -      // for the regular debug case.
   1.141 -      assert(!bad, "Bad JNI oop argument");
   1.142 +    intptr_t v = _value[_pos];
   1.143 +    if (v != 0) {
   1.144 +      // v is a "handle" referring to an oop, cast to integral type.
   1.145 +      // There shouldn't be any handles in very low memory.
   1.146 +      guarantee((size_t)v >= (size_t)os::vm_page_size(),
   1.147 +                "Bad JNI oop argument");
   1.148 +      // Verify the pointee.
   1.149 +      oop vv = resolve_indirect_oop(v, _value_state[_pos]);
   1.150 +      guarantee(vv->is_oop_or_null(true),
   1.151 +                "Bad JNI oop argument");
   1.152      }
   1.153  
   1.154 -    check_value(true);
   1.155 +    check_value(true);          // Verify value state.
   1.156    }
   1.157  
   1.158    void do_bool()                       { check_int(T_BOOLEAN);       }
   1.159 @@ -536,8 +571,7 @@
   1.160  };
   1.161  
   1.162  
   1.163 -void JavaCallArguments::verify(methodHandle method, BasicType return_type,
   1.164 -  Thread *thread) {
   1.165 +void JavaCallArguments::verify(methodHandle method, BasicType return_type) {
   1.166    guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
   1.167  
   1.168    // Treat T_OBJECT and T_ARRAY as the same
   1.169 @@ -546,7 +580,11 @@
   1.170    // Check that oop information is correct
   1.171    Symbol* signature = method->signature();
   1.172  
   1.173 -  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
   1.174 +  SignatureChekker sc(signature,
   1.175 +                      return_type,
   1.176 +                      method->is_static(),
   1.177 +                      _value_state,
   1.178 +                      _value);
   1.179    sc.iterate_parameters();
   1.180    sc.check_doing_return(true);
   1.181    sc.iterate_returntype();

mercurial