src/share/vm/runtime/javaCalls.hpp

changeset 9669
32bc598624bd
parent 6198
55fb97c4c58d
child 9703
2fdf635bcf28
     1.1 --- a/src/share/vm/runtime/javaCalls.hpp	Thu Nov 05 11:42:42 2015 +0100
     1.2 +++ b/src/share/vm/runtime/javaCalls.hpp	Tue May 07 20:38:26 2019 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2013, 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 @@ -92,25 +92,42 @@
    1.11     _default_size = 8    // Must be at least # of arguments in JavaCalls methods
    1.12    };
    1.13  
    1.14 -  intptr_t    _value_buffer [_default_size + 1];
    1.15 -  bool        _is_oop_buffer[_default_size + 1];
    1.16 +  intptr_t    _value_buffer      [_default_size + 1];
    1.17 +  u_char      _value_state_buffer[_default_size + 1];
    1.18  
    1.19    intptr_t*   _value;
    1.20 -  bool*       _is_oop;
    1.21 +  u_char*     _value_state;
    1.22    int         _size;
    1.23    int         _max_size;
    1.24    bool        _start_at_zero;      // Support late setting of receiver
    1.25  
    1.26    void initialize() {
    1.27      // Starts at first element to support set_receiver.
    1.28 -    _value    = &_value_buffer[1];
    1.29 -    _is_oop   = &_is_oop_buffer[1];
    1.30 +    _value       = &_value_buffer[1];
    1.31 +    _value_state = &_value_state_buffer[1];
    1.32  
    1.33      _max_size = _default_size;
    1.34      _size = 0;
    1.35      _start_at_zero = false;
    1.36    }
    1.37  
    1.38 +  // Helper for push_oop and the like.  The value argument is a
    1.39 +  // "handle" that refers to an oop.  We record the address of the
    1.40 +  // handle rather than the designated oop.  The handle is later
    1.41 +  // resolved to the oop by parameters().  This delays the exposure of
    1.42 +  // naked oops until it is GC-safe.
    1.43 +  template<typename T>
    1.44 +  inline int push_oop_impl(T handle, int size) {
    1.45 +    // JNITypes::put_obj expects an oop value, so we play fast and
    1.46 +    // loose with the type system.  The cast from handle type to oop
    1.47 +    // *must* use a C-style cast.  In a product build it performs a
    1.48 +    // reinterpret_cast. In a debug build (more accurately, in a
    1.49 +    // CHECK_UNHANDLED_OOPS build) it performs a static_cast, invoking
    1.50 +    // the debug-only oop class's conversion from void* constructor.
    1.51 +    JNITypes::put_obj((oop)handle, _value, size); // Updates size.
    1.52 +    return size;                // Return the updated size.
    1.53 +  }
    1.54 +
    1.55   public:
    1.56    JavaCallArguments() { initialize(); }
    1.57  
    1.58 @@ -121,11 +138,12 @@
    1.59  
    1.60    JavaCallArguments(int max_size) {
    1.61      if (max_size > _default_size) {
    1.62 -      _value  = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
    1.63 -      _is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1);
    1.64 +      _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
    1.65 +      _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1);
    1.66  
    1.67 -      // Reserve room for potential receiver in value and is_oop
    1.68 -      _value++; _is_oop++;
    1.69 +      // Reserve room for potential receiver in value and state
    1.70 +      _value++;
    1.71 +      _value_state++;
    1.72  
    1.73        _max_size = max_size;
    1.74        _size = 0;
    1.75 @@ -135,25 +153,52 @@
    1.76      }
    1.77    }
    1.78  
    1.79 -  inline void push_oop(Handle h)    { _is_oop[_size] = true;
    1.80 -                               JNITypes::put_obj((oop)h.raw_value(), _value, _size); }
    1.81 +  // The possible values for _value_state elements.
    1.82 +  enum {
    1.83 +    value_state_primitive,
    1.84 +    value_state_oop,
    1.85 +    value_state_handle,
    1.86 +    value_state_jobject,
    1.87 +    value_state_limit
    1.88 +  };
    1.89  
    1.90 -  inline void push_int(int i)       { _is_oop[_size] = false;
    1.91 -                               JNITypes::put_int(i, _value, _size); }
    1.92 +  inline void push_oop(Handle h) {
    1.93 +    _value_state[_size] = value_state_handle;
    1.94 +    _size = push_oop_impl(h.raw_value(), _size);
    1.95 +  }
    1.96  
    1.97 -  inline void push_double(double d) { _is_oop[_size] = false; _is_oop[_size + 1] = false;
    1.98 -                               JNITypes::put_double(d, _value, _size); }
    1.99 +  inline void push_jobject(jobject h) {
   1.100 +    _value_state[_size] = value_state_jobject;
   1.101 +    _size = push_oop_impl(h, _size);
   1.102 +  }
   1.103  
   1.104 -  inline void push_long(jlong l)    { _is_oop[_size] = false; _is_oop[_size + 1] = false;
   1.105 -                               JNITypes::put_long(l, _value, _size); }
   1.106 +  inline void push_int(int i) {
   1.107 +    _value_state[_size] = value_state_primitive;
   1.108 +    JNITypes::put_int(i, _value, _size);
   1.109 +  }
   1.110  
   1.111 -  inline void push_float(float f)   { _is_oop[_size] = false;
   1.112 -                               JNITypes::put_float(f, _value, _size); }
   1.113 +  inline void push_double(double d) {
   1.114 +    _value_state[_size] = value_state_primitive;
   1.115 +    _value_state[_size + 1] = value_state_primitive;
   1.116 +    JNITypes::put_double(d, _value, _size);
   1.117 +  }
   1.118 +
   1.119 +  inline void push_long(jlong l) {
   1.120 +    _value_state[_size] = value_state_primitive;
   1.121 +    _value_state[_size + 1] = value_state_primitive;
   1.122 +    JNITypes::put_long(l, _value, _size);
   1.123 +  }
   1.124 +
   1.125 +  inline void push_float(float f) {
   1.126 +    _value_state[_size] = value_state_primitive;
   1.127 +    JNITypes::put_float(f, _value, _size);
   1.128 +  }
   1.129  
   1.130    // receiver
   1.131    Handle receiver() {
   1.132      assert(_size > 0, "must at least be one argument");
   1.133 -    assert(_is_oop[0], "first argument must be an oop");
   1.134 +    assert(_value_state[0] == value_state_handle,
   1.135 +           "first argument must be an oop");
   1.136      assert(_value[0] != 0, "receiver must be not-null");
   1.137      return Handle((oop*)_value[0], false);
   1.138    }
   1.139 @@ -161,11 +206,11 @@
   1.140    void set_receiver(Handle h) {
   1.141      assert(_start_at_zero == false, "can only be called once");
   1.142      _start_at_zero = true;
   1.143 -    _is_oop--;
   1.144 +    _value_state--;
   1.145      _value--;
   1.146      _size++;
   1.147 -    _is_oop[0] = true;
   1.148 -    _value[0] = (intptr_t)h.raw_value();
   1.149 +    _value_state[0] = value_state_handle;
   1.150 +    push_oop_impl(h.raw_value(), 0);
   1.151    }
   1.152  
   1.153    // Converts all Handles to oops, and returns a reference to parameter vector
   1.154 @@ -173,7 +218,7 @@
   1.155    int   size_of_parameters() const { return _size; }
   1.156  
   1.157    // Verify that pushed arguments fits a given method
   1.158 -  void verify(methodHandle method, BasicType return_type, Thread *thread);
   1.159 +  void verify(methodHandle method, BasicType return_type);
   1.160  };
   1.161  
   1.162  // All calls to Java have to go via JavaCalls. Sets up the stack frame

mercurial