< prev index next >

src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com
   1 /*
   2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 172   assert(_cstring_table != NULL, "invariant");
 173   _cstring_query = str;
 174   const CStringEntry& entry = _cstring_table->lookup_put(hash, str);
 175   if (_class_unload) {
 176     entry.set_unloading();
 177   }
 178   if (leakp) {
 179     entry.set_leakp();
 180   }
 181   return entry.id();
 182 }
 183 
 184 /*
 185 * jsr292 anonymous classes symbol is the external name +
 186 * the identity_hashcode slash appended:
 187 *   java.lang.invoke.LambdaForm$BMH/22626602
 188 *
 189 * caller needs ResourceMark
 190 */
 191 
 192 uintptr_t JfrSymbolId::unsafe_anonymous_klass_name_hash(const InstanceKlass* ik) {
 193   assert(ik != NULL, "invariant");
 194   assert(ik->is_unsafe_anonymous(), "invariant");
 195   const oop mirror = ik->java_mirror_no_keepalive();
 196   assert(mirror != NULL, "invariant");
 197   return (uintptr_t)mirror->identity_hash();
 198 }
 199 
 200 static const char* create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t hash) {
 201   assert(ik != NULL, "invariant");
 202   assert(ik->is_unsafe_anonymous(), "invariant");
 203   assert(hash != 0, "invariant");
 204   char* anonymous_symbol = NULL;
 205   const oop mirror = ik->java_mirror_no_keepalive();
 206   assert(mirror != NULL, "invariant");
 207   char hash_buf[40];
 208   sprintf(hash_buf, "/" UINTX_FORMAT, hash);
 209   const size_t hash_len = strlen(hash_buf);
 210   const size_t result_len = ik->name()->utf8_length();
 211   anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
 212   ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
 213   assert(strlen(anonymous_symbol) == result_len, "invariant");
 214   strcpy(anonymous_symbol + result_len, hash_buf);
 215   assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant");
 216   return anonymous_symbol;
 217 }
 218 
 219 bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) {
 220   assert(k != NULL, "invariant");
 221   return k->is_instance_klass() && ((const InstanceKlass*)k)->is_unsafe_anonymous();


 222 }
 223 
 224 traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const InstanceKlass* ik, bool leakp) {
 225   assert(ik != NULL, "invariant");
 226   assert(ik->is_unsafe_anonymous(), "invariant");
 227   const uintptr_t hash = unsafe_anonymous_klass_name_hash(ik);
 228   const char* const anonymous_klass_symbol = create_unsafe_anonymous_klass_symbol(ik, hash);
 229   return mark(hash, anonymous_klass_symbol, leakp);
 230 }
 231 
 232 traceid JfrSymbolId::mark(const Klass* k, bool leakp) {
 233   assert(k != NULL, "invariant");
 234   traceid symbol_id = 0;
 235   if (is_unsafe_anonymous_klass(k)) {
 236     assert(k->is_instance_klass(), "invariant");
 237     symbol_id = mark_unsafe_anonymous_klass_name((const InstanceKlass*)k, leakp);
 238   }
 239   if (0 == symbol_id) {
 240     Symbol* const sym = k->name();
 241     if (sym != NULL) {
 242       symbol_id = mark(sym, leakp);
 243     }
 244   }
 245   assert(symbol_id > 0, "a symbol handler must mark the symbol for writing");
 246   return symbol_id;
 247 }
 248 
 249 JfrArtifactSet::JfrArtifactSet(bool class_unload) : _symbol_id(new JfrSymbolId()),
 250                                                     _klass_list(NULL),
 251                                                     _total_count(0) {
 252   initialize(class_unload);
 253   assert(_klass_list != NULL, "invariant");
 254 }
 255 
 256 static const size_t initial_class_list_size = 200;
 257 


 259   assert(_symbol_id != NULL, "invariant");
 260   if (clear) {
 261     _symbol_id->clear();
 262   }
 263   _symbol_id->set_class_unload(class_unload);
 264   _total_count = 0;
 265   // resource allocation
 266   _klass_list = new GrowableArray<const Klass*>(initial_class_list_size, false, mtTracing);
 267 }
 268 
 269 JfrArtifactSet::~JfrArtifactSet() {
 270   _symbol_id->clear();
 271   delete _symbol_id;
 272   // _klass_list will be cleared by a ResourceMark
 273 }
 274 
 275 traceid JfrArtifactSet::bootstrap_name(bool leakp) {
 276   return _symbol_id->bootstrap_name(leakp);
 277 }
 278 
 279 traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass, bool leakp) {
 280   assert(klass->is_instance_klass(), "invariant");
 281   return _symbol_id->mark_unsafe_anonymous_klass_name((const InstanceKlass*)klass, leakp);
 282 }
 283 
 284 traceid JfrArtifactSet::mark(uintptr_t hash, const Symbol* sym, bool leakp) {
 285   return _symbol_id->mark(hash, sym, leakp);
 286 }
 287 
 288 traceid JfrArtifactSet::mark(const Klass* klass, bool leakp) {
 289   return _symbol_id->mark(klass, leakp);
 290 }
 291 
 292 traceid JfrArtifactSet::mark(const Symbol* symbol, bool leakp) {
 293   return _symbol_id->mark(symbol, leakp);
 294 }
 295 
 296 traceid JfrArtifactSet::mark(uintptr_t hash, const char* const str, bool leakp) {
 297   return _symbol_id->mark(hash, str, leakp);
 298 }
 299 
 300 bool JfrArtifactSet::has_klass_entries() const {
 301   return _klass_list->is_nonempty();
   1 /*
   2  * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 172   assert(_cstring_table != NULL, "invariant");
 173   _cstring_query = str;
 174   const CStringEntry& entry = _cstring_table->lookup_put(hash, str);
 175   if (_class_unload) {
 176     entry.set_unloading();
 177   }
 178   if (leakp) {
 179     entry.set_leakp();
 180   }
 181   return entry.id();
 182 }
 183 
 184 /*
 185 * jsr292 anonymous classes symbol is the external name +
 186 * the identity_hashcode slash appended:
 187 *   java.lang.invoke.LambdaForm$BMH/22626602
 188 *
 189 * caller needs ResourceMark
 190 */
 191 
 192 uintptr_t JfrSymbolId::hidden_or_anon_klass_name_hash(const InstanceKlass* ik) {
 193   assert(ik != NULL, "invariant");
 194   assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant");
 195   const oop mirror = ik->java_mirror_no_keepalive();
 196   assert(mirror != NULL, "invariant");
 197   return (uintptr_t)mirror->identity_hash();
 198 }
 199 
 200 static const char* create_hidden_or_anon_klass_symbol(const InstanceKlass* ik, uintptr_t hash) {
 201   assert(ik != NULL, "invariant");
 202   assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant");
 203   assert(hash != 0, "invariant");
 204   char* hidden_or_anon_symbol = NULL;
 205   const oop mirror = ik->java_mirror_no_keepalive();
 206   assert(mirror != NULL, "invariant");
 207   char hash_buf[40];
 208   sprintf(hash_buf, "/" UINTX_FORMAT, hash);
 209   const size_t hash_len = strlen(hash_buf);
 210   const size_t result_len = ik->name()->utf8_length();
 211   hidden_or_anon_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
 212   ik->name()->as_klass_external_name(hidden_or_anon_symbol, (int)result_len + 1);
 213   assert(strlen(hidden_or_anon_symbol) == result_len, "invariant");
 214   strcpy(hidden_or_anon_symbol + result_len, hash_buf);
 215   assert(strlen(hidden_or_anon_symbol) == result_len + hash_len, "invariant");
 216   return hidden_or_anon_symbol;
 217 }
 218 
 219 bool JfrSymbolId::is_hidden_or_anon_klass(const Klass* k) {
 220   assert(k != NULL, "invariant");
 221   return k->is_instance_klass() &&
 222     (((const InstanceKlass*)k)->is_unsafe_anonymous() ||
 223      ((const InstanceKlass*)k)->is_hidden());
 224 }
 225 
 226 traceid JfrSymbolId::mark_hidden_or_anon_klass_name(const InstanceKlass* ik, bool leakp) {
 227   assert(ik != NULL, "invariant");
 228   assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant");
 229   const uintptr_t hash = hidden_or_anon_klass_name_hash(ik);
 230   const char* const hidden_or_anon_symbol = create_hidden_or_anon_klass_symbol(ik, hash);
 231   return mark(hash, hidden_or_anon_symbol, leakp);
 232 }
 233 
 234 traceid JfrSymbolId::mark(const Klass* k, bool leakp) {
 235   assert(k != NULL, "invariant");
 236   traceid symbol_id = 0;
 237   if (is_hidden_or_anon_klass(k)) {
 238     assert(k->is_instance_klass(), "invariant");
 239     symbol_id = mark_hidden_or_anon_klass_name((const InstanceKlass*)k, leakp);
 240   }
 241   if (0 == symbol_id) {
 242     Symbol* const sym = k->name();
 243     if (sym != NULL) {
 244       symbol_id = mark(sym, leakp);
 245     }
 246   }
 247   assert(symbol_id > 0, "a symbol handler must mark the symbol for writing");
 248   return symbol_id;
 249 }
 250 
 251 JfrArtifactSet::JfrArtifactSet(bool class_unload) : _symbol_id(new JfrSymbolId()),
 252                                                     _klass_list(NULL),
 253                                                     _total_count(0) {
 254   initialize(class_unload);
 255   assert(_klass_list != NULL, "invariant");
 256 }
 257 
 258 static const size_t initial_class_list_size = 200;
 259 


 261   assert(_symbol_id != NULL, "invariant");
 262   if (clear) {
 263     _symbol_id->clear();
 264   }
 265   _symbol_id->set_class_unload(class_unload);
 266   _total_count = 0;
 267   // resource allocation
 268   _klass_list = new GrowableArray<const Klass*>(initial_class_list_size, false, mtTracing);
 269 }
 270 
 271 JfrArtifactSet::~JfrArtifactSet() {
 272   _symbol_id->clear();
 273   delete _symbol_id;
 274   // _klass_list will be cleared by a ResourceMark
 275 }
 276 
 277 traceid JfrArtifactSet::bootstrap_name(bool leakp) {
 278   return _symbol_id->bootstrap_name(leakp);
 279 }
 280 
 281 traceid JfrArtifactSet::mark_hidden_or_anon_klass_name(const Klass* klass, bool leakp) {
 282   assert(klass->is_instance_klass(), "invariant");
 283   return _symbol_id->mark_hidden_or_anon_klass_name((const InstanceKlass*)klass, leakp);
 284 }
 285 
 286 traceid JfrArtifactSet::mark(uintptr_t hash, const Symbol* sym, bool leakp) {
 287   return _symbol_id->mark(hash, sym, leakp);
 288 }
 289 
 290 traceid JfrArtifactSet::mark(const Klass* klass, bool leakp) {
 291   return _symbol_id->mark(klass, leakp);
 292 }
 293 
 294 traceid JfrArtifactSet::mark(const Symbol* symbol, bool leakp) {
 295   return _symbol_id->mark(symbol, leakp);
 296 }
 297 
 298 traceid JfrArtifactSet::mark(uintptr_t hash, const char* const str, bool leakp) {
 299   return _symbol_id->mark(hash, str, leakp);
 300 }
 301 
 302 bool JfrArtifactSet::has_klass_entries() const {
 303   return _klass_list->is_nonempty();
< prev index next >