49 static u8 checkpoint_id = 0; |
49 static u8 checkpoint_id = 0; |
50 |
50 |
51 // creates a unique id by combining a checkpoint relative symbol id (2^24) |
51 // creates a unique id by combining a checkpoint relative symbol id (2^24) |
52 // with the current checkpoint id (2^40) |
52 // with the current checkpoint id (2^40) |
53 #define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id))) |
53 #define CREATE_SYMBOL_ID(sym_id) (((u8)((checkpoint_id << 24) | sym_id))) |
|
54 #define CREATE_PACKAGE_ID(pkg_id) (((u8)((checkpoint_id << 24) | pkg_id))) |
54 |
55 |
55 typedef const Klass* KlassPtr; |
56 typedef const Klass* KlassPtr; |
56 typedef const ClassLoaderData* CldPtr; |
57 typedef const ClassLoaderData* CldPtr; |
57 typedef const Method* MethodPtr; |
58 typedef const Method* MethodPtr; |
58 typedef const Symbol* SymbolPtr; |
59 typedef const Symbol* SymbolPtr; |
59 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr; |
60 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr; |
60 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr; |
61 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr; |
|
62 |
|
63 inline uintptr_t package_name_hash(const char *s) { |
|
64 uintptr_t val = 0; |
|
65 while (*s != 0) { |
|
66 val = *s++ + 31 * val; |
|
67 } |
|
68 return val; |
|
69 } |
|
70 |
|
71 static traceid package_id(KlassPtr klass, JfrArtifactSet* artifacts) { |
|
72 assert(klass != NULL, "invariant"); |
|
73 char* klass_name = klass->name()->as_C_string(); // uses ResourceMark declared in JfrTypeSet::serialize() |
|
74 const char* pkg_name = ClassLoader::package_from_name(klass_name, NULL); |
|
75 if (pkg_name == NULL) { |
|
76 return 0; |
|
77 } |
|
78 return CREATE_PACKAGE_ID(artifacts->markPackage(pkg_name, package_name_hash(pkg_name))); |
|
79 } |
61 |
80 |
62 static traceid cld_id(CldPtr cld) { |
81 static traceid cld_id(CldPtr cld) { |
63 assert(cld != NULL, "invariant"); |
82 assert(cld != NULL, "invariant"); |
64 return cld->is_anonymous() ? 0 : TRACE_ID(cld); |
83 return cld->is_anonymous() ? 0 : TRACE_ID(cld); |
65 } |
84 } |
109 if (theklass->oop_is_objArray()) { |
128 if (theklass->oop_is_objArray()) { |
110 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast((Klass*)klass); |
129 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast((Klass*)klass); |
111 theklass = obj_arr_klass->bottom_klass(); |
130 theklass = obj_arr_klass->bottom_klass(); |
112 } |
131 } |
113 if (theklass->oop_is_instance()) { |
132 if (theklass->oop_is_instance()) { |
114 pkg_id = 0; |
133 pkg_id = package_id(theklass, artifacts); |
115 } else { |
134 } else { |
116 assert(theklass->oop_is_typeArray(), "invariant"); |
135 assert(theklass->oop_is_typeArray(), "invariant"); |
117 } |
136 } |
118 const traceid symbol_id = artifacts->mark(klass); |
137 const traceid symbol_id = artifacts->mark(klass); |
119 assert(symbol_id > 0, "need to have an address for symbol!"); |
138 assert(symbol_id > 0, "need to have an address for symbol!"); |
152 return 1; |
171 return 1; |
153 } |
172 } |
154 |
173 |
155 typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method> MethodWriterImplTarget; |
174 typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method> MethodWriterImplTarget; |
156 typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
175 typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
|
176 |
|
177 int write__artifact__package(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) { |
|
178 assert(writer != NULL, "invariant"); |
|
179 assert(artifacts != NULL, "invariant"); |
|
180 assert(p != NULL, "invariant"); |
|
181 |
|
182 CStringEntryPtr entry = (CStringEntryPtr)p; |
|
183 const traceid package_name_symbol_id = artifacts->mark(entry->value(), package_name_hash(entry->value())); |
|
184 assert(package_name_symbol_id > 0, "invariant"); |
|
185 writer->write((traceid)CREATE_PACKAGE_ID(entry->id())); |
|
186 writer->write((traceid)CREATE_SYMBOL_ID(package_name_symbol_id)); |
|
187 writer->write((bool)true); // exported |
|
188 return 1; |
|
189 } |
157 |
190 |
158 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) { |
191 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) { |
159 assert(c != NULL, "invariant"); |
192 assert(c != NULL, "invariant"); |
160 CldPtr cld = (CldPtr)c; |
193 CldPtr cld = (CldPtr)c; |
161 assert(!cld->is_anonymous(), "invariant"); |
194 assert(!cld->is_anonymous(), "invariant"); |
434 CompositeKlassCallback callback(&ckwr); |
467 CompositeKlassCallback callback(&ckwr); |
435 _subsystem_callback = &callback; |
468 _subsystem_callback = &callback; |
436 do_klasses(); |
469 do_klasses(); |
437 } |
470 } |
438 |
471 |
|
472 typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__package> PackageEntryWriterImpl; |
|
473 typedef JfrArtifactWriterHost<PackageEntryWriterImpl, TYPE_PACKAGE> PackageEntryWriter; |
|
474 |
|
475 void JfrTypeSet::write_package_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
476 assert(_artifacts->has_klass_entries(), "invariant"); |
|
477 assert(writer != NULL, "invariant"); |
|
478 // below jdk9 there is no oop for packages, so nothing to do with leakp_writer |
|
479 // just write packages |
|
480 PackageEntryWriter pw(writer, _artifacts, _class_unload); |
|
481 _artifacts->iterate_packages(pw); |
|
482 } |
|
483 |
439 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
484 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
440 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; |
485 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; |
441 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; |
486 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; |
442 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
487 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
443 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback; |
488 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback; |
683 |
728 |
684 // write order is important because an individual write step |
729 // write order is important because an individual write step |
685 // might tag an artifact to be written in a subsequent step |
730 // might tag an artifact to be written in a subsequent step |
686 write_klass_constants(writer, leakp_writer); |
731 write_klass_constants(writer, leakp_writer); |
687 if (_artifacts->has_klass_entries()) { |
732 if (_artifacts->has_klass_entries()) { |
|
733 write_package_constants(writer, leakp_writer); |
688 write_class_loader_constants(writer, leakp_writer); |
734 write_class_loader_constants(writer, leakp_writer); |
689 write_method_constants(writer, leakp_writer); |
735 write_method_constants(writer, leakp_writer); |
690 write_symbol_constants(writer, leakp_writer); |
736 write_symbol_constants(writer, leakp_writer); |
691 clear_artifacts(_artifacts, class_unload); |
737 clear_artifacts(_artifacts, class_unload); |
692 } |
738 } |