< prev index next >

src/hotspot/share/classfile/classFileParser.cpp

Print this page
@@ -34,10 +34,13 @@
  #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"

@@ -1077,10 +1080,11 @@
      _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;

@@ -1113,10 +1117,15 @@
  
    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:

@@ -1685,10 +1694,17 @@
  
      // 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;

@@ -2118,10 +2134,18 @@
      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;

@@ -2130,10 +2154,15 @@
  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);

@@ -5806,10 +5835,27 @@
      }
    }
  
    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 >