< prev index next > src/hotspot/share/classfile/classFileParser.cpp
Print this page
#include "classfile/javaClasses.inline.hpp"
#include "classfile/moduleEntry.hpp"
#include "classfile/packageEntry.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
+ #if INCLUDE_TSAN
+ #include "classfile/tsanIgnoreList.hpp"
+ #endif // INCLUDE_TSAN
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
_method_LambdaForm_Compiled,
_method_Hidden,
_method_HotSpotIntrinsicCandidate,
_jdk_internal_vm_annotation_Contended,
_field_Stable,
+ _field_TsanIgnore,
_jdk_internal_vm_annotation_ReservedStackAccess,
_annotation_LIMIT
};
const Location _location;
int _annotations_present;
bool is_contended() const { return has_annotation(_jdk_internal_vm_annotation_Contended); }
void set_stable(bool stable) { set_annotation(_field_Stable); }
bool is_stable() const { return has_annotation(_field_Stable); }
+
+ #if INCLUDE_TSAN
+ void set_tsan_ignore(bool tsan_ignore) { set_annotation(_field_TsanIgnore); }
+ bool is_tsan_ignore() const { return has_annotation(_field_TsanIgnore); }
+ #endif // INCLUDE_TSAN
};
// This class also doubles as a holder for metadata cleanup.
class ClassFileParser::FieldAnnotationCollector : public AnnotationCollector {
private:
// Remember how many oops we encountered and compute allocation type
const FieldAllocationType atype = fac->update(is_static, type);
field->set_allocation_type(atype);
+ TSAN_RUNTIME_ONLY(
+ if (ThreadSanitizerIgnoreFile != NULL &&
+ TsanIgnoreList::match(_class_name, name, type)) {
+ parsed_annotations.set_tsan_ignore(true);
+ }
+ );
+
// After field is initialized with type, we can augment it with aux info
if (parsed_annotations.has_any_annotations()) {
parsed_annotations.apply_to(field);
if (field->is_contended()) {
_has_contended_fields = true;
case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ReservedStackAccess_signature): {
if (_location != _in_method) break; // only allow for methods
if (RestrictReservedStack && !privileged) break; // honor privileges
return _jdk_internal_vm_annotation_ReservedStackAccess;
}
+ #if INCLUDE_TSAN
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_util_concurrent_annotation_LazyInit): {
+ if (_location != _in_field) {
+ break; // only allow for fields
+ }
+ return _field_TsanIgnore;
+ }
+ #endif // INCLUDE_TSAN
default: {
break;
}
}
return AnnotationCollector::_unknown;
void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
if (is_contended())
f->set_contended_group(contended_group());
if (is_stable())
f->set_stable(true);
+ TSAN_RUNTIME_ONLY(
+ if (is_tsan_ignore())
+ f->set_tsan_ignore(true);
+ );
+
}
ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
// If there's an error deallocate metadata for field annotations
MetadataFactory::free_array<u1>(_loader_data, _field_annotations);
}
}
ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);
+ #if INCLUDE_TSAN
+ if (ThreadSanitizer && !ik->is_interface()) {
+ ik->ensure_space_for_methodids(0);
+ int num_methods = ik->methods()->length();
+ for (int index = 0; index < num_methods; index++) {
+ // Make sure each method has a jmethodID.
+ // This allows us to avoid allocating jmethodIDs during program execution.
+ jmethodID id = ik->methods()->at(index)->jmethod_id();
+ #ifdef ASSERT
+ u8 id_u8 = reinterpret_cast<u8>(id);
+ assert((id_u8 & right_n_bits(3)) == 0, "jmethodID is not aligned");
+ assert((id_u8 & left_n_bits(17)) == 0, "jmethodID is not aligned");
+ #endif
+ }
+ }
+ #endif // INCLUDE_TSAN
+
if (!is_internal()) {
if (log_is_enabled(Info, class, load)) {
ResourceMark rm;
const char* module_name = (module_entry->name() == NULL) ? UNNAMED_MODULE : module_entry->name()->as_C_string();
ik->print_class_load_logging(_loader_data, module_name, _stream);
< prev index next >