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.