src/share/vm/runtime/sharedRuntime.cpp

changeset 1642
74c848d437ab
parent 1640
5fcfaa1ad96f
child 1651
7f8790caccb0
child 1685
3f5b7efb9642
     1.1 --- a/src/share/vm/runtime/sharedRuntime.cpp	Mon Feb 01 16:49:49 2010 -0800
     1.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp	Wed Feb 03 12:28:30 2010 -0800
     1.3 @@ -1806,55 +1806,78 @@
     1.4  class AdapterFingerPrint : public CHeapObj {
     1.5   private:
     1.6    union {
     1.7 -    signed char  _compact[12];
     1.8 -    int          _compact_int[3];
     1.9 -    intptr_t*    _fingerprint;
    1.10 +    int  _compact[3];
    1.11 +    int* _fingerprint;
    1.12    } _value;
    1.13 -  int _length; // A negative length indicates that _value._fingerprint is the array.
    1.14 -               // Otherwise it's in the compact form.
    1.15 +  int _length; // A negative length indicates the fingerprint is in the compact form,
    1.16 +               // Otherwise _value._fingerprint is the array.
    1.17  
    1.18 - public:
    1.19 -  AdapterFingerPrint(int total_args_passed, VMRegPair* regs) {
    1.20 -    assert(sizeof(_value._compact) == sizeof(_value._compact_int), "must match");
    1.21 -    _length = total_args_passed * 2;
    1.22 -    if (_length < (int)sizeof(_value._compact)) {
    1.23 -      _value._compact_int[0] = _value._compact_int[1] = _value._compact_int[2] = 0;
    1.24 -      // Storing the signature encoded as signed chars hits about 98%
    1.25 -      // of the time.
    1.26 -      signed char* ptr = _value._compact;
    1.27 -      int o = 0;
    1.28 -      for (int i = 0; i < total_args_passed; i++) {
    1.29 -        VMRegPair pair = regs[i];
    1.30 -        intptr_t v1 = pair.first()->value();
    1.31 -        intptr_t v2 = pair.second()->value();
    1.32 -        if (v1 == (signed char) v1 &&
    1.33 -            v2 == (signed char) v2) {
    1.34 -          _value._compact[o++] = v1;
    1.35 -          _value._compact[o++] = v2;
    1.36 -        } else {
    1.37 -          goto big;
    1.38 +  // Remap BasicTypes that are handled equivalently by the adapters.
    1.39 +  // These are correct for the current system but someday it might be
    1.40 +  // necessary to make this mapping platform dependent.
    1.41 +  static BasicType adapter_encoding(BasicType in) {
    1.42 +    assert((~0xf & in) == 0, "must fit in 4 bits");
    1.43 +    switch(in) {
    1.44 +      case T_BOOLEAN:
    1.45 +      case T_BYTE:
    1.46 +      case T_SHORT:
    1.47 +      case T_CHAR:
    1.48 +        // There are all promoted to T_INT in the calling convention
    1.49 +        return T_INT;
    1.50 +
    1.51 +      case T_OBJECT:
    1.52 +      case T_ARRAY:
    1.53 +        if (!TaggedStackInterpreter) {
    1.54 +#ifdef _LP64
    1.55 +          return T_LONG;
    1.56 +#else
    1.57 +          return T_INT;
    1.58 +#endif
    1.59          }
    1.60 -      }
    1.61 -      _length = -_length;
    1.62 -      return;
    1.63 -    }
    1.64 -  big:
    1.65 -    _value._fingerprint = NEW_C_HEAP_ARRAY(intptr_t, _length);
    1.66 -    int o = 0;
    1.67 -    for (int i = 0; i < total_args_passed; i++) {
    1.68 -      VMRegPair pair = regs[i];
    1.69 -      intptr_t v1 = pair.first()->value();
    1.70 -      intptr_t v2 = pair.second()->value();
    1.71 -      _value._fingerprint[o++] = v1;
    1.72 -      _value._fingerprint[o++] = v2;
    1.73 +        return T_OBJECT;
    1.74 +
    1.75 +      case T_INT:
    1.76 +      case T_LONG:
    1.77 +      case T_FLOAT:
    1.78 +      case T_DOUBLE:
    1.79 +      case T_VOID:
    1.80 +        return in;
    1.81 +
    1.82 +      default:
    1.83 +        ShouldNotReachHere();
    1.84 +        return T_CONFLICT;
    1.85      }
    1.86    }
    1.87  
    1.88 -  AdapterFingerPrint(AdapterFingerPrint* orig) {
    1.89 -    _length = orig->_length;
    1.90 -    _value = orig->_value;
    1.91 -    // take ownership of any storage by destroying the length
    1.92 -    orig->_length = 0;
    1.93 + public:
    1.94 +  AdapterFingerPrint(int total_args_passed, BasicType* sig_bt) {
    1.95 +    // The fingerprint is based on the BasicType signature encoded
    1.96 +    // into an array of ints with four entries per int.
    1.97 +    int* ptr;
    1.98 +    int len = (total_args_passed + 3) >> 2;
    1.99 +    if (len <= (int)(sizeof(_value._compact) / sizeof(int))) {
   1.100 +      _value._compact[0] = _value._compact[1] = _value._compact[2] = 0;
   1.101 +      // Storing the signature encoded as signed chars hits about 98%
   1.102 +      // of the time.
   1.103 +      _length = -len;
   1.104 +      ptr = _value._compact;
   1.105 +    } else {
   1.106 +      _length = len;
   1.107 +      _value._fingerprint = NEW_C_HEAP_ARRAY(int, _length);
   1.108 +      ptr = _value._fingerprint;
   1.109 +    }
   1.110 +
   1.111 +    // Now pack the BasicTypes with 4 per int
   1.112 +    int sig_index = 0;
   1.113 +    for (int index = 0; index < len; index++) {
   1.114 +      int value = 0;
   1.115 +      for (int byte = 0; byte < 4; byte++) {
   1.116 +        if (sig_index < total_args_passed) {
   1.117 +          value = (value << 4) | adapter_encoding(sig_bt[sig_index++]);
   1.118 +        }
   1.119 +      }
   1.120 +      ptr[index] = value;
   1.121 +    }
   1.122    }
   1.123  
   1.124    ~AdapterFingerPrint() {
   1.125 @@ -1863,11 +1886,7 @@
   1.126      }
   1.127    }
   1.128  
   1.129 -  AdapterFingerPrint* allocate() {
   1.130 -    return new AdapterFingerPrint(this);
   1.131 -  }
   1.132 -
   1.133 -  intptr_t value(int index) {
   1.134 +  int value(int index) {
   1.135      if (_length < 0) {
   1.136        return _value._compact[index];
   1.137      }
   1.138 @@ -1883,9 +1902,9 @@
   1.139    }
   1.140  
   1.141    unsigned int compute_hash() {
   1.142 -    intptr_t hash = 0;
   1.143 +    int hash = 0;
   1.144      for (int i = 0; i < length(); i++) {
   1.145 -      intptr_t v = value(i);
   1.146 +      int v = value(i);
   1.147        hash = (hash << 8) ^ v ^ (hash >> 5);
   1.148      }
   1.149      return (unsigned int)hash;
   1.150 @@ -1904,9 +1923,9 @@
   1.151        return false;
   1.152      }
   1.153      if (_length < 0) {
   1.154 -      return _value._compact_int[0] == other->_value._compact_int[0] &&
   1.155 -             _value._compact_int[1] == other->_value._compact_int[1] &&
   1.156 -             _value._compact_int[2] == other->_value._compact_int[2];
   1.157 +      return _value._compact[0] == other->_value._compact[0] &&
   1.158 +             _value._compact[1] == other->_value._compact[1] &&
   1.159 +             _value._compact[2] == other->_value._compact[2];
   1.160      } else {
   1.161        for (int i = 0; i < _length; i++) {
   1.162          if (_value._fingerprint[i] != other->_value._fingerprint[i]) {
   1.163 @@ -1954,10 +1973,15 @@
   1.164      add_entry(index, entry);
   1.165    }
   1.166  
   1.167 +  void free_entry(AdapterHandlerEntry* entry) {
   1.168 +    entry->deallocate();
   1.169 +    BasicHashtable::free_entry(entry);
   1.170 +  }
   1.171 +
   1.172    // Find a entry with the same fingerprint if it exists
   1.173 -  AdapterHandlerEntry* lookup(int total_args_passed, VMRegPair* regs) {
   1.174 +  AdapterHandlerEntry* lookup(int total_args_passed, BasicType* sig_bt) {
   1.175      debug_only(_lookups++);
   1.176 -    AdapterFingerPrint fp(total_args_passed, regs);
   1.177 +    AdapterFingerPrint fp(total_args_passed, sig_bt);
   1.178      unsigned int hash = fp.compute_hash();
   1.179      int index = hash_to_index(hash);
   1.180      for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) {
   1.181 @@ -2129,17 +2153,26 @@
   1.182      }
   1.183      assert(i == total_args_passed, "");
   1.184  
   1.185 -    // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
   1.186 -    int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
   1.187 +    // Lookup method signature's fingerprint
   1.188 +    entry = _adapters->lookup(total_args_passed, sig_bt);
   1.189  
   1.190 -    // Lookup method signature's fingerprint
   1.191 -    entry = _adapters->lookup(total_args_passed, regs);
   1.192 +#ifdef ASSERT
   1.193 +    AdapterHandlerEntry* shared_entry = NULL;
   1.194 +    if (VerifyAdapterSharing && entry != NULL) {
   1.195 +      shared_entry = entry;
   1.196 +      entry = NULL;
   1.197 +    }
   1.198 +#endif
   1.199 +
   1.200      if (entry != NULL) {
   1.201        return entry;
   1.202      }
   1.203  
   1.204 +    // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
   1.205 +    int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
   1.206 +
   1.207      // Make a C heap allocated version of the fingerprint to store in the adapter
   1.208 -    fingerprint = new AdapterFingerPrint(total_args_passed, regs);
   1.209 +    fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt);
   1.210  
   1.211      // Create I2C & C2I handlers
   1.212  
   1.213 @@ -2158,6 +2191,20 @@
   1.214                                                       regs,
   1.215                                                       fingerprint);
   1.216  
   1.217 +#ifdef ASSERT
   1.218 +      if (VerifyAdapterSharing) {
   1.219 +        if (shared_entry != NULL) {
   1.220 +          assert(shared_entry->compare_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt),
   1.221 +                 "code must match");
   1.222 +          // Release the one just created and return the original
   1.223 +          _adapters->free_entry(entry);
   1.224 +          return shared_entry;
   1.225 +        } else  {
   1.226 +          entry->save_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt);
   1.227 +        }
   1.228 +      }
   1.229 +#endif
   1.230 +
   1.231        B = BufferBlob::create(AdapterHandlerEntry::name, &buffer);
   1.232        NOT_PRODUCT(code_size = buffer.code_size());
   1.233      }
   1.234 @@ -2212,6 +2259,44 @@
   1.235      _c2i_unverified_entry += delta;
   1.236  }
   1.237  
   1.238 +
   1.239 +void AdapterHandlerEntry::deallocate() {
   1.240 +  delete _fingerprint;
   1.241 +#ifdef ASSERT
   1.242 +  if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code);
   1.243 +  if (_saved_sig)  FREE_C_HEAP_ARRAY(Basictype, _saved_sig);
   1.244 +#endif
   1.245 +}
   1.246 +
   1.247 +
   1.248 +#ifdef ASSERT
   1.249 +// Capture the code before relocation so that it can be compared
   1.250 +// against other versions.  If the code is captured after relocation
   1.251 +// then relative instructions won't be equivalent.
   1.252 +void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
   1.253 +  _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length);
   1.254 +  _code_length = length;
   1.255 +  memcpy(_saved_code, buffer, length);
   1.256 +  _total_args_passed = total_args_passed;
   1.257 +  _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed);
   1.258 +  memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType));
   1.259 +}
   1.260 +
   1.261 +
   1.262 +bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
   1.263 +  if (length != _code_length) {
   1.264 +    return false;
   1.265 +  }
   1.266 +  for (int i = 0; i < length; i++) {
   1.267 +    if (buffer[i] != _saved_code[i]) {
   1.268 +      return false;
   1.269 +    }
   1.270 +  }
   1.271 +  return true;
   1.272 +}
   1.273 +#endif
   1.274 +
   1.275 +
   1.276  // Create a native wrapper for this native method.  The wrapper converts the
   1.277  // java compiled calling convention to the native convention, handlizes
   1.278  // arguments, and transitions to native.  On return from the native we transition

mercurial