Reviewers: ulan,

Message:
Committed patchset #2 manually as r18199 (presubmit successful).

Description:
Experimental scanner multithreading fix.

Many ExperimentalScanners might get created simultaneously in different threads,
so we cannot just keep track of them without locking. Moving the bookkeeping
into Isolate.

[email protected]
BUG=

Committed: https://code.google.com/p/v8/source/detail?r=18199

Please review this at https://codereview.chromium.org/99243002/

SVN Base: https://v8.googlecode.com/svn/branches/experimental/parser

Affected files (+58, -37 lines):
  M src/isolate.h
  M src/isolate.cc
  M src/lexer/experimental-scanner.h
  M src/lexer/experimental-scanner.cc


Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 740cce00476a3ab66ea35fbf48e411f7bbc06da2..975e84d4ddb12453fa0b22cfd1a30807a59cf8ba 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -40,6 +40,7 @@
 #include "heap-profiler.h"
 #include "hydrogen.h"
 #include "isolate-inl.h"
+#include "lexer/experimental-scanner.h"
 #include "lithium-allocator.h"
 #include "log.h"
 #include "messages.h"
@@ -1298,6 +1299,22 @@ bool Isolate::IsErrorObject(Handle<Object> obj) {
   return false;
 }

+
+void Isolate::UpdateScannersAfterGC(v8::Isolate* isolate,
+                                    GCType,
+                                    GCCallbackFlags) {
+  reinterpret_cast<i::Isolate*>(isolate)->UpdateScannersAfterGC();
+}
+
+
+void Isolate::UpdateScannersAfterGC() {
+  for (std::set<ScannerBase*>::const_iterator it = scanners_.begin();
+       it != scanners_.end();
+       ++it)
+    (*it)->UpdateBufferBasedOnHandle();
+}
+
+
 static int fatal_exception_depth = 0;

 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
@@ -2521,6 +2538,23 @@ Object* Isolate::FindCodeObject(Address a) {
 }


+void Isolate::AddScanner(ScannerBase* scanner) {
+  if (scanners_.empty()) {
+    heap()->AddGCEpilogueCallback(
+        &Isolate::UpdateScannersAfterGC, kGCTypeAll, false);
+  }
+  scanners_.insert(scanner);
+}
+
+
+void Isolate::RemoveScanner(ScannerBase* scanner) {
+  scanners_.erase(scanner);
+  if (scanners_.empty()) {
+    heap()->RemoveGCEpilogueCallback(&Isolate::UpdateScannersAfterGC);
+  }
+}
+
+
 #ifdef DEBUG
 #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
Index: src/isolate.h
diff --git a/src/isolate.h b/src/isolate.h
index c13714f68246cd7f39702c3a1e998ae91df7a116..12afd5f22848231da249f5509ab9b7a5db5198e3 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -28,6 +28,8 @@
 #ifndef V8_ISOLATE_H_
 #define V8_ISOLATE_H_

+#include <set>
+
 #include "../include/v8-debug.h"
 #include "allocation.h"
 #include "apiutils.h"
@@ -82,6 +84,7 @@ class RegExpStack;
 class SaveContext;
 class UnicodeCache;
 class ConsStringIteratorOp;
+class ScannerBase;
 class StringTracker;
 class StubCache;
 class SweeperThread;
@@ -1142,6 +1145,9 @@ class Isolate {
   // Given an address occupied by a live code object, return that object.
   Object* FindCodeObject(Address a);

+  void AddScanner(ScannerBase* scanner);
+  void RemoveScanner(ScannerBase* scanner);
+
  private:
   Isolate();

@@ -1254,6 +1260,9 @@ class Isolate {
   // the Error object.
   bool IsErrorObject(Handle<Object> obj);

+  static void UpdateScannersAfterGC(v8::Isolate*, GCType, GCCallbackFlags);
+  void UpdateScannersAfterGC();
+
   Atomic32 id_;
   EntryStackItem* entry_stack_;
   int stack_trace_nesting_level_;
@@ -1377,6 +1386,10 @@ class Isolate {
   // Counts deopt points if deopt_every_n_times is enabled.
   unsigned int stress_deopt_count_;

+ // Stores information about the ScannerBase objects currently alive, so that
+  // we can update the raw string pointers they hold after GC.
+  std::set<ScannerBase*> scanners_;
+
   friend class ExecutionAccess;
   friend class HandleScopeImplementer;
   friend class IsolateInitializer;
Index: src/lexer/experimental-scanner.cc
diff --git a/src/lexer/experimental-scanner.cc b/src/lexer/experimental-scanner.cc index a314e63e0959f41562f09fb284cb613a8f60f010..d354908e6c4619d134af34616e08c6a670ee2f78 100644
--- a/src/lexer/experimental-scanner.cc
+++ b/src/lexer/experimental-scanner.cc
@@ -30,17 +30,6 @@
 namespace v8 {
 namespace internal {

-std::set<ScannerBase*>* ScannerBase::scanners_ = NULL;
-
-void ScannerBase::UpdateBuffersAfterGC(v8::Isolate*, GCType, GCCallbackFlags) {
-  if (!scanners_) return;
-  for (std::set<ScannerBase*>::const_iterator it = scanners_->begin();
-       it != scanners_->end();
-       ++it)
-    (*it)->SetBufferBasedOnHandle();
-}
-
-
 template<>
const uint8_t* ExperimentalScanner<uint8_t>::GetNewBufferBasedOnHandle() const {
   String::FlatContent content = source_handle_->GetFlatContent();
Index: src/lexer/experimental-scanner.h
diff --git a/src/lexer/experimental-scanner.h b/src/lexer/experimental-scanner.h index a049e9f8703f0d2d1c05a9e452cdcf45cbe8cefd..cf35594997a6747e57e3ec1bcfa9f3aa3f6816d4 100644
--- a/src/lexer/experimental-scanner.h
+++ b/src/lexer/experimental-scanner.h
@@ -28,8 +28,6 @@
 #ifndef V8_LEXER_EXPERIMENTAL_SCANNER_H
 #define V8_LEXER_EXPERIMENTAL_SCANNER_H

-#include <set>
-
 #include "compiler.h"
 #include "isolate.h"
 #include "scanner.h"  // UnicodeCache.
@@ -70,22 +68,11 @@ class ScannerBase {
       harmony_numeric_literals_(false),
       harmony_modules_(false),
       harmony_scoping_(false) {
-    if (!scanners_) {
-      scanners_ = new std::set<ScannerBase*>();
- isolate->heap()->AddGCEpilogueCallback(&ScannerBase::UpdateBuffersAfterGC,
-                                             kGCTypeAll, false);
-    }
-    scanners_->insert(this);
+    isolate->AddScanner(this);
   }

   virtual ~ScannerBase() {
-    scanners_->erase(this);
-    if (scanners_->empty()) {
-      isolate_->heap()->RemoveGCEpilogueCallback(
-          &ScannerBase::UpdateBuffersAfterGC);
-      delete scanners_;
-      scanners_ = NULL;
-    }
+    isolate_->RemoveScanner(this);
   }

   // Has to be called after creating the scanner and setting the flags.
@@ -111,6 +98,10 @@ class ScannerBase {
   virtual Location octal_position() const = 0;
   virtual void clear_octal_position() = 0;

+ // Sets the raw string pointer based on the string handle. Needs to be called
+  // right after GC.
+  virtual void UpdateBufferBasedOnHandle() = 0;
+
   // Returns the next token and advances input.
   Token::Value Next() {
     has_line_terminator_before_next_ = false;
@@ -260,9 +251,6 @@ class ScannerBase {
   };

   virtual void Scan() = 0;
-  virtual void SetBufferBasedOnHandle() = 0;
-
-  static void UpdateBuffersAfterGC(v8::Isolate*, GCType, GCCallbackFlags);
virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal) = 0;

   Isolate* isolate_;
@@ -280,9 +268,6 @@ class ScannerBase {
   bool harmony_numeric_literals_;
   bool harmony_modules_;
   bool harmony_scoping_;
-
- private:
-  static std::set<ScannerBase*>* scanners_;
 };


@@ -301,7 +286,7 @@ class ExperimentalScanner : public ScannerBase {
         marker_(NULL),
         last_octal_end_(NULL) {
     ASSERT(source->IsFlat());
-    SetBufferBasedOnHandle();
+    UpdateBufferBasedOnHandle();
current_.beg_pos = current_.end_pos = next_.beg_pos = next_.end_pos = 0;
   }

@@ -320,10 +305,7 @@ class ExperimentalScanner : public ScannerBase {
     last_octal_end_ = NULL;
   }

- protected:
-  virtual void Scan();
-
-  virtual void SetBufferBasedOnHandle() {
+  virtual void UpdateBufferBasedOnHandle() {
// We get a raw pointer from the Handle, but we also update it every time
     // there is a GC, so it is safe.
     DisallowHeapAllocation no_gc;
@@ -340,6 +322,9 @@ class ExperimentalScanner : public ScannerBase {
     }
   }

+ protected:
+  virtual void Scan();
+
   const Char* GetNewBufferBasedOnHandle() const;

   virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to