1.1 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Mon Apr 11 08:51:53 2016 +0200 1.2 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Mon Jun 29 21:30:26 2020 +0100 1.3 @@ -51,6 +51,7 @@ 1.4 // creates a unique id by combining a checkpoint relative symbol id (2^24) 1.5 // with the current checkpoint id (2^40) 1.6 #define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id))) 1.7 +#define CREATE_PACKAGE_ID(pkg_id) (((u8)((checkpoint_id << 24) | pkg_id))) 1.8 1.9 typedef const Klass* KlassPtr; 1.10 typedef const ClassLoaderData* CldPtr; 1.11 @@ -59,6 +60,24 @@ 1.12 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr; 1.13 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr; 1.14 1.15 +inline uintptr_t package_name_hash(const char *s) { 1.16 + uintptr_t val = 0; 1.17 + while (*s != 0) { 1.18 + val = *s++ + 31 * val; 1.19 + } 1.20 + return val; 1.21 +} 1.22 + 1.23 +static traceid package_id(KlassPtr klass, JfrArtifactSet* artifacts) { 1.24 + assert(klass != NULL, "invariant"); 1.25 + char* klass_name = klass->name()->as_C_string(); // uses ResourceMark declared in JfrTypeSet::serialize() 1.26 + const char* pkg_name = ClassLoader::package_from_name(klass_name, NULL); 1.27 + if (pkg_name == NULL) { 1.28 + return 0; 1.29 + } 1.30 + return CREATE_PACKAGE_ID(artifacts->markPackage(pkg_name, package_name_hash(pkg_name))); 1.31 +} 1.32 + 1.33 static traceid cld_id(CldPtr cld) { 1.34 assert(cld != NULL, "invariant"); 1.35 return cld->is_anonymous() ? 0 : TRACE_ID(cld); 1.36 @@ -111,7 +130,7 @@ 1.37 theklass = obj_arr_klass->bottom_klass(); 1.38 } 1.39 if (theklass->oop_is_instance()) { 1.40 - pkg_id = 0; 1.41 + pkg_id = package_id(theklass, artifacts); 1.42 } else { 1.43 assert(theklass->oop_is_typeArray(), "invariant"); 1.44 } 1.45 @@ -155,6 +174,20 @@ 1.46 typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method> MethodWriterImplTarget; 1.47 typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; 1.48 1.49 +int write__artifact__package(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) { 1.50 + assert(writer != NULL, "invariant"); 1.51 + assert(artifacts != NULL, "invariant"); 1.52 + assert(p != NULL, "invariant"); 1.53 + 1.54 + CStringEntryPtr entry = (CStringEntryPtr)p; 1.55 + const traceid package_name_symbol_id = artifacts->mark(entry->value(), package_name_hash(entry->value())); 1.56 + assert(package_name_symbol_id > 0, "invariant"); 1.57 + writer->write((traceid)CREATE_PACKAGE_ID(entry->id())); 1.58 + writer->write((traceid)CREATE_SYMBOL_ID(package_name_symbol_id)); 1.59 + writer->write((bool)true); // exported 1.60 + return 1; 1.61 +} 1.62 + 1.63 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) { 1.64 assert(c != NULL, "invariant"); 1.65 CldPtr cld = (CldPtr)c; 1.66 @@ -436,6 +469,18 @@ 1.67 do_klasses(); 1.68 } 1.69 1.70 +typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__package> PackageEntryWriterImpl; 1.71 +typedef JfrArtifactWriterHost<PackageEntryWriterImpl, TYPE_PACKAGE> PackageEntryWriter; 1.72 + 1.73 +void JfrTypeSet::write_package_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { 1.74 + assert(_artifacts->has_klass_entries(), "invariant"); 1.75 + assert(writer != NULL, "invariant"); 1.76 + // below jdk9 there is no oop for packages, so nothing to do with leakp_writer 1.77 + // just write packages 1.78 + PackageEntryWriter pw(writer, _artifacts, _class_unload); 1.79 + _artifacts->iterate_packages(pw); 1.80 +} 1.81 + 1.82 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; 1.83 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; 1.84 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; 1.85 @@ -685,6 +730,7 @@ 1.86 // might tag an artifact to be written in a subsequent step 1.87 write_klass_constants(writer, leakp_writer); 1.88 if (_artifacts->has_klass_entries()) { 1.89 + write_package_constants(writer, leakp_writer); 1.90 write_class_loader_constants(writer, leakp_writer); 1.91 write_method_constants(writer, leakp_writer); 1.92 write_symbol_constants(writer, leakp_writer);