diff a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp
--- a/src/hotspot/share/classfile/classFileParser.cpp
+++ b/src/hotspot/share/classfile/classFileParser.cpp
@@ -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);
