https://github.com/google/glog/issues/649
https://github.com/google/glog/pull/650
https://github.com/google/glog/commit/86fea1ab254c463cbb72e5ce8bcc6855bc4e1e9c

--- a/src/glog/vlog_is_on.h.in
+++ b/src/glog/vlog_is_on.h.in
@@ -81,10 +81,10 @@
 // parsing of --vmodule flag and/or SetVLOGLevel calls.
 #define VLOG_IS_ON(verboselevel)                                \
   __extension__  \
-  ({ static @ac_google_namespace@::int32* vlocal__ = NULL;           \
+  ({ static @ac_google_namespace@::SiteFlag vlocal__{NULL, NULL, 0, NULL};       \
      @ac_google_namespace@::int32 verbose_level__ = (verboselevel);                    \
-     (vlocal__ == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \
-                        __FILE__, verbose_level__) : *vlocal__ >= verbose_level__); \
+     (vlocal__.level == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \
+                        __FILE__, verbose_level__) : *vlocal__.level >= verbose_level__); \
   })
 #else
 // GNU extensions not available, so we do not support --vmodule.
@@ -105,6 +105,13 @@
 
 // Various declarations needed for VLOG_IS_ON above: =========================
 
+struct SiteFlag {
+  @ac_google_namespace@::int32* level;
+  const char* base_name;
+  size_t base_len;
+  SiteFlag* next;
+};
+
 // Helper routine which determines the logging info for a particalur VLOG site.
 //   site_flag     is the address of the site-local pointer to the controlling
 //                 verbosity level
@@ -114,7 +121,7 @@
 // We will return the return value for VLOG_IS_ON
 // and if possible set *site_flag appropriately.
 extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
-    @ac_google_namespace@::int32** site_flag,
+    @ac_google_namespace@::SiteFlag* site_flag,
     @ac_google_namespace@::int32* site_default,
     const char* fname,
     @ac_google_namespace@::int32 verbose_level);
--- a/src/logging_unittest.cc
+++ b/src/logging_unittest.cc
@@ -98,6 +98,7 @@
 static void TestRawLogging();
 static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
 static void TestLoggingLevels();
+static void TestVLogModule();
 static void TestLogString();
 static void TestLogSink();
 static void TestLogToString();
@@ -223,6 +224,7 @@
   TestLogging(true);
   TestRawLogging();
   TestLoggingLevels();
+  TestVLogModule();
   TestLogString();
   TestLogSink();
   TestLogToString();
@@ -453,6 +455,24 @@
   LogWithLevels(1, GLOG_FATAL, false, true);
 }
 
+int TestVlogHelper() {
+  if (VLOG_IS_ON(1)) {
+    return 1;
+  }
+  return 0;
+}
+
+void TestVLogModule() {
+  int c = TestVlogHelper();
+  EXPECT_EQ(0, c);
+
+#if defined(__GNUC__)
+  EXPECT_EQ(0, SetVLOGLevel("logging_unittest", 1));
+  c = TestVlogHelper();
+  EXPECT_EQ(1, c);
+#endif
+}
+
 TEST(DeathRawCHECK, logging) {
   ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
                "RAW: Check false failed: failure 1");
--- a/src/vlog_is_on.cc
+++ b/src/vlog_is_on.cc
@@ -125,6 +125,8 @@
 // Pointer to head of the VModuleInfo list.
 // It's a map from module pattern to logging level for those module(s).
 static VModuleInfo* vmodule_list = 0;
+static SiteFlag* cached_site_list = 0;
+
 // Boolean initialization flag.
 static bool inited_vmodule = false;
 
@@ -190,6 +192,23 @@
       info->vlog_level = log_level;
       info->next = vmodule_list;
       vmodule_list = info;
+
+      SiteFlag** item_ptr = &cached_site_list;
+      SiteFlag* item = cached_site_list;
+
+      // We traverse the list fully because the pattern can match several items
+      // from the list.
+      while (item) {
+        if (SafeFNMatch_(module_pattern, pattern_len, item->base_name,
+                         item->base_len)) {
+          // Redirect the cached value to its module override.
+          item->level = &info->vlog_level;
+          *item_ptr = item->next;  // Remove the item from the list.
+        } else {
+          item_ptr = &item->next;
+        }
+        item = *item_ptr;
+      }
     }
   }
   RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level);
@@ -198,7 +217,7 @@
 
 // NOTE: Individual VLOG statements cache the integer log level pointers.
 // NOTE: This function must not allocate memory or require any locks.
-bool InitVLOG3__(int32** site_flag, int32* site_default,
+bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
                  const char* fname, int32 verbose_level) {
   MutexLock l(&vmodule_lock);
   bool read_vmodule_flag = inited_vmodule;
@@ -211,10 +230,17 @@
   int old_errno = errno;
 
   // site_default normally points to FLAGS_v
-  int32* site_flag_value = site_default;
+  int32* site_flag_value = level_default;
 
   // Get basename for file
   const char* base = strrchr(fname, '/');
+
+#ifdef _WIN32
+  if (!base) {
+    base = strrchr(fname, '\\');
+  }
+#endif
+
   base = base ? (base+1) : fname;
   const char* base_end = strchr(base, '.');
   size_t base_length = base_end ? size_t(base_end - base) : strlen(base);
@@ -244,7 +270,20 @@
   ANNOTATE_BENIGN_RACE(site_flag,
                        "*site_flag may be written by several threads,"
                        " but the value will be the same");
-  if (read_vmodule_flag) *site_flag = site_flag_value;
+  if (read_vmodule_flag) {
+    site_flag->level = site_flag_value;
+    // If VLOG flag has been cached to the default site pointer,
+    // we want to add to the cached list in order to invalidate in case
+    // SetVModule is called afterwards with new modules.
+    // The performance penalty here is neglible, because InitVLOG3__ is called
+    // once per site.
+    if (site_flag_value == level_default && !site_flag->base_name) {
+      site_flag->base_name = base;
+      site_flag->base_len = base_length;
+      site_flag->next = cached_site_list;
+      cached_site_list = site_flag;
+    }
+  }
 
   // restore the errno in case something recoverable went wrong during
   // the initialization of the VLOG mechanism (see above note "protect the..")