Make the Isolate parameter mandatory in Locker and Unlocker classes.
Note that leaving out the Isolate parameter previously had a very special meaning, namely "use the *default* Isolate", i.e. the one magically created at program initialization time. All other API entries use the meaning "current Isolate", which is different in a multi-threaded setting and confusing. Temporarily disabled deprecations until Chrome is ready. BUG=v8:2487 Review URL: https://codereview.chromium.org/11970009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13419 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ca78326b66
commit
fab9a39d9d
87
include/v8.h
87
include/v8.h
@ -38,6 +38,9 @@
|
||||
#ifndef V8_H_
|
||||
#define V8_H_
|
||||
|
||||
// TODO(svenpanne) Remove me when the Chrome bindings are adapted.
|
||||
#define V8_DISABLE_DEPRECATIONS 1
|
||||
|
||||
#include "v8stdint.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -3879,21 +3882,19 @@ class V8EXPORT Context {
|
||||
|
||||
|
||||
/**
|
||||
* Multiple threads in V8 are allowed, but only one thread at a time
|
||||
* is allowed to use any given V8 isolate. See Isolate class
|
||||
* comments. The definition of 'using V8 isolate' includes
|
||||
* accessing handles or holding onto object pointers obtained
|
||||
* from V8 handles while in the particular V8 isolate. It is up
|
||||
* to the user of V8 to ensure (perhaps with locking) that this
|
||||
* constraint is not violated. In addition to any other synchronization
|
||||
* mechanism that may be used, the v8::Locker and v8::Unlocker classes
|
||||
* must be used to signal thead switches to V8.
|
||||
* Multiple threads in V8 are allowed, but only one thread at a time is allowed
|
||||
* to use any given V8 isolate, see the comments in the Isolate class. The
|
||||
* definition of 'using a V8 isolate' includes accessing handles or holding onto
|
||||
* object pointers obtained from V8 handles while in the particular V8 isolate.
|
||||
* It is up to the user of V8 to ensure, perhaps with locking, that this
|
||||
* constraint is not violated. In addition to any other synchronization
|
||||
* mechanism that may be used, the v8::Locker and v8::Unlocker classes must be
|
||||
* used to signal thead switches to V8.
|
||||
*
|
||||
* v8::Locker is a scoped lock object. While it's
|
||||
* active (i.e. between its construction and destruction) the current thread is
|
||||
* allowed to use the locked isolate. V8 guarantees that an isolate can be
|
||||
* locked by at most one thread at any time. In other words, the scope of a
|
||||
* v8::Locker is a critical section.
|
||||
* v8::Locker is a scoped lock object. While it's active, i.e. between its
|
||||
* construction and destruction, the current thread is allowed to use the locked
|
||||
* isolate. V8 guarantees that an isolate can be locked by at most one thread at
|
||||
* any time. In other words, the scope of a v8::Locker is a critical section.
|
||||
*
|
||||
* Sample usage:
|
||||
* \code
|
||||
@ -3907,9 +3908,9 @@ class V8EXPORT Context {
|
||||
* } // Destructor called here
|
||||
* \endcode
|
||||
*
|
||||
* If you wish to stop using V8 in a thread A you can do this either
|
||||
* by destroying the v8::Locker object as above or by constructing a
|
||||
* v8::Unlocker object:
|
||||
* If you wish to stop using V8 in a thread A you can do this either by
|
||||
* destroying the v8::Locker object as above or by constructing a v8::Unlocker
|
||||
* object:
|
||||
*
|
||||
* \code
|
||||
* {
|
||||
@ -3922,19 +3923,17 @@ class V8EXPORT Context {
|
||||
* isolate->Enter();
|
||||
* \endcode
|
||||
*
|
||||
* The Unlocker object is intended for use in a long-running callback
|
||||
* from V8, where you want to release the V8 lock for other threads to
|
||||
* use.
|
||||
* The Unlocker object is intended for use in a long-running callback from V8,
|
||||
* where you want to release the V8 lock for other threads to use.
|
||||
*
|
||||
* The v8::Locker is a recursive lock. That is, you can lock more than
|
||||
* once in a given thread. This can be useful if you have code that can
|
||||
* be called either from code that holds the lock or from code that does
|
||||
* not. The Unlocker is not recursive so you can not have several
|
||||
* Unlockers on the stack at once, and you can not use an Unlocker in a
|
||||
* thread that is not inside a Locker's scope.
|
||||
* The v8::Locker is a recursive lock, i.e. you can lock more than once in a
|
||||
* given thread. This can be useful if you have code that can be called either
|
||||
* from code that holds the lock or from code that does not. The Unlocker is
|
||||
* not recursive so you can not have several Unlockers on the stack at once, and
|
||||
* you can not use an Unlocker in a thread that is not inside a Locker's scope.
|
||||
*
|
||||
* An unlocker will unlock several lockers if it has to and reinstate
|
||||
* the correct depth of locking on its destruction. eg.:
|
||||
* An unlocker will unlock several lockers if it has to and reinstate the
|
||||
* correct depth of locking on its destruction, e.g.:
|
||||
*
|
||||
* \code
|
||||
* // V8 not locked.
|
||||
@ -3957,17 +3956,23 @@ class V8EXPORT Context {
|
||||
* }
|
||||
* // V8 Now no longer locked.
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
*/
|
||||
class V8EXPORT Unlocker {
|
||||
public:
|
||||
/**
|
||||
* Initialize Unlocker for a given Isolate. NULL means default isolate.
|
||||
* Initialize Unlocker for a given Isolate.
|
||||
*/
|
||||
explicit Unlocker(Isolate* isolate = NULL);
|
||||
V8_INLINE(explicit Unlocker(Isolate* isolate)) { Initialize(isolate); }
|
||||
|
||||
/**
|
||||
* Deprecated. Use Isolate version instead.
|
||||
*/
|
||||
V8_DEPRECATED(Unlocker());
|
||||
|
||||
~Unlocker();
|
||||
private:
|
||||
void Initialize(Isolate* isolate);
|
||||
|
||||
internal::Isolate* isolate_;
|
||||
};
|
||||
|
||||
@ -3975,9 +3980,15 @@ class V8EXPORT Unlocker {
|
||||
class V8EXPORT Locker {
|
||||
public:
|
||||
/**
|
||||
* Initialize Locker for a given Isolate. NULL means default isolate.
|
||||
* Initialize Locker for a given Isolate.
|
||||
*/
|
||||
explicit Locker(Isolate* isolate = NULL);
|
||||
V8_INLINE(explicit Locker(Isolate* isolate)) { Initialize(isolate); }
|
||||
|
||||
/**
|
||||
* Deprecated. Use Isolate version instead.
|
||||
*/
|
||||
V8_DEPRECATED(Locker());
|
||||
|
||||
~Locker();
|
||||
|
||||
/**
|
||||
@ -3995,10 +4006,10 @@ class V8EXPORT Locker {
|
||||
static void StopPreemption();
|
||||
|
||||
/**
|
||||
* Returns whether or not the locker for a given isolate, or default isolate
|
||||
* if NULL is given, is locked by the current thread.
|
||||
* Returns whether or not the locker for a given isolate, is locked by the
|
||||
* current thread.
|
||||
*/
|
||||
static bool IsLocked(Isolate* isolate = NULL);
|
||||
static bool IsLocked(Isolate* isolate);
|
||||
|
||||
/**
|
||||
* Returns whether v8::Locker is being used by this V8 instance.
|
||||
@ -4006,6 +4017,8 @@ class V8EXPORT Locker {
|
||||
static bool IsActive();
|
||||
|
||||
private:
|
||||
void Initialize(Isolate* isolate);
|
||||
|
||||
bool has_lock_;
|
||||
bool top_level_;
|
||||
internal::Isolate* isolate_;
|
||||
|
@ -214,7 +214,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
debug_message_context = v8::Persistent<v8::Context>::New(context);
|
||||
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(v8::Isolate::GetCurrent());
|
||||
|
||||
if (support_callback) {
|
||||
v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
|
||||
@ -265,7 +265,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
bool RunCppCycle(v8::Handle<v8::Script> script, v8::Local<v8::Context> context,
|
||||
bool report_exceptions) {
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(v8::Isolate::GetCurrent());
|
||||
#endif // ENABLE_DEBUGGER_SUPPORT
|
||||
|
||||
v8::Handle<v8::String> fun_name = v8::String::New("ProcessLine");
|
||||
@ -420,7 +420,7 @@ v8::Handle<v8::String> ReadLine() {
|
||||
char* res;
|
||||
{
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(v8::Isolate::GetCurrent());
|
||||
#endif // ENABLE_DEBUGGER_SUPPORT
|
||||
res = fgets(buffer, kBufferSize, stdin);
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ RemoteDebuggerEvent* RemoteDebugger::GetEvent() {
|
||||
|
||||
|
||||
void RemoteDebugger::HandleMessageReceived(char* message) {
|
||||
Locker lock;
|
||||
Locker lock(v8::Isolate::GetCurrent());
|
||||
HandleScope scope;
|
||||
|
||||
// Print the event details.
|
||||
@ -302,7 +302,7 @@ void RemoteDebugger::HandleMessageReceived(char* message) {
|
||||
|
||||
|
||||
void RemoteDebugger::HandleKeyboardCommand(char* command) {
|
||||
Locker lock;
|
||||
Locker lock(v8::Isolate::GetCurrent());
|
||||
HandleScope scope;
|
||||
|
||||
// Convert the debugger command to a JSON debugger request.
|
||||
|
22
src/d8.cc
22
src/d8.cc
@ -886,7 +886,7 @@ Handle<Value> Shell::Uint8ClampedArray(const Arguments& args) {
|
||||
|
||||
|
||||
Handle<Value> Shell::Yield(const Arguments& args) {
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(args.GetIsolate());
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
@ -1093,8 +1093,8 @@ void Shell::AddHistogramSample(void* histogram, int sample) {
|
||||
}
|
||||
|
||||
|
||||
void Shell::InstallUtilityScript() {
|
||||
Locker lock;
|
||||
void Shell::InstallUtilityScript(Isolate* isolate) {
|
||||
Locker lock(isolate);
|
||||
HandleScope scope;
|
||||
// If we use the utility context, we have to set the security tokens so that
|
||||
// utility, evaluation and debug context can all access each other.
|
||||
@ -1272,7 +1272,7 @@ void Shell::Initialize(Isolate* isolate) {
|
||||
void Shell::InitializeDebugger(Isolate* isolate) {
|
||||
if (options.test_shell) return;
|
||||
#ifndef V8_SHARED
|
||||
Locker lock;
|
||||
Locker lock(isolate);
|
||||
HandleScope scope;
|
||||
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
|
||||
utility_context_ = Context::New(NULL, global_template);
|
||||
@ -1490,7 +1490,7 @@ Handle<String> Shell::ReadFile(Isolate* isolate, const char* name) {
|
||||
|
||||
|
||||
void Shell::RunShell(Isolate* isolate) {
|
||||
Locker locker;
|
||||
Locker locker(isolate);
|
||||
Context::Scope context_scope(evaluation_context_);
|
||||
HandleScope outer_scope;
|
||||
Handle<String> name = String::New("(d8)");
|
||||
@ -1540,7 +1540,7 @@ void ShellThread::Run() {
|
||||
}
|
||||
|
||||
// Prepare the context for this thread.
|
||||
Locker locker;
|
||||
Locker locker(isolate_);
|
||||
HandleScope outer_scope;
|
||||
Persistent<Context> thread_context =
|
||||
Shell::CreateEvaluationContext(isolate_);
|
||||
@ -1839,7 +1839,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
|
||||
}
|
||||
#endif // V8_SHARED
|
||||
{ // NOLINT
|
||||
Locker lock;
|
||||
Locker lock(isolate);
|
||||
HandleScope scope;
|
||||
Persistent<Context> context = CreateEvaluationContext(isolate);
|
||||
if (options.last_run) {
|
||||
@ -1849,7 +1849,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
|
||||
// If the interactive debugger is enabled make sure to activate
|
||||
// it before running the files passed on the command line.
|
||||
if (i::FLAG_debugger) {
|
||||
InstallUtilityScript();
|
||||
InstallUtilityScript(isolate);
|
||||
}
|
||||
#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
|
||||
}
|
||||
@ -1887,7 +1887,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
if (threads.length() > 0 && options.use_preemption) {
|
||||
Locker lock;
|
||||
Locker lock(isolate);
|
||||
Locker::StopPreemption();
|
||||
}
|
||||
#endif // V8_SHARED
|
||||
@ -1934,7 +1934,7 @@ int Shell::Main(int argc, char* argv[]) {
|
||||
#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
|
||||
// Run remote debugger if requested, but never on --test
|
||||
if (i::FLAG_remote_debugger && !options.test_shell) {
|
||||
InstallUtilityScript();
|
||||
InstallUtilityScript(isolate);
|
||||
RunRemoteDebugger(i::FLAG_debugger_port);
|
||||
return 0;
|
||||
}
|
||||
@ -1947,7 +1947,7 @@ int Shell::Main(int argc, char* argv[]) {
|
||||
&& !options.test_shell ) {
|
||||
#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
|
||||
if (!i::FLAG_debugger) {
|
||||
InstallUtilityScript();
|
||||
InstallUtilityScript(isolate);
|
||||
}
|
||||
#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
|
||||
RunShell(isolate);
|
||||
|
2
src/d8.h
2
src/d8.h
@ -381,7 +381,7 @@ class Shell : public i::AllStatic {
|
||||
static i::Mutex* context_mutex_;
|
||||
|
||||
static Counter* GetCounter(const char* name, bool is_histogram);
|
||||
static void InstallUtilityScript();
|
||||
static void InstallUtilityScript(Isolate* isolate);
|
||||
#endif // V8_SHARED
|
||||
static void Initialize(Isolate* isolate);
|
||||
static void InitializeDebugger(Isolate* isolate);
|
||||
|
@ -3767,6 +3767,7 @@ void MessageDispatchHelperThread::Schedule() {
|
||||
|
||||
|
||||
void MessageDispatchHelperThread::Run() {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
while (true) {
|
||||
sem_->Wait();
|
||||
{
|
||||
@ -3774,8 +3775,8 @@ void MessageDispatchHelperThread::Run() {
|
||||
already_signalled_ = false;
|
||||
}
|
||||
{
|
||||
Locker locker;
|
||||
Isolate::Current()->debugger()->CallMessageDispatchHandler();
|
||||
Locker locker(reinterpret_cast<v8::Isolate*>(isolate));
|
||||
isolate->debugger()->CallMessageDispatchHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -408,9 +408,9 @@ void Isolate::EnterDefaultIsolate() {
|
||||
}
|
||||
|
||||
|
||||
Isolate* Isolate::GetDefaultIsolateForLocking() {
|
||||
v8::Isolate* Isolate::GetDefaultIsolateForLocking() {
|
||||
EnsureDefaultIsolate();
|
||||
return default_isolate_;
|
||||
return reinterpret_cast<v8::Isolate*>(default_isolate_);
|
||||
}
|
||||
|
||||
|
||||
@ -1743,7 +1743,7 @@ void Isolate::Deinit() {
|
||||
delete deoptimizer_data_;
|
||||
deoptimizer_data_ = NULL;
|
||||
if (FLAG_preemption) {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(reinterpret_cast<v8::Isolate*>(this));
|
||||
v8::Locker::StopPreemption();
|
||||
}
|
||||
builtins_.TearDown();
|
||||
@ -2034,7 +2034,7 @@ bool Isolate::Init(Deserializer* des) {
|
||||
}
|
||||
|
||||
if (FLAG_preemption) {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(reinterpret_cast<v8::Isolate*>(this));
|
||||
v8::Locker::StartPreemption(100);
|
||||
}
|
||||
|
||||
|
@ -1070,6 +1070,11 @@ class Isolate {
|
||||
return &optimizing_compiler_thread_;
|
||||
}
|
||||
|
||||
// PreInits and returns a default isolate. Needed when a new thread tries
|
||||
// to create a Locker for the first time (the lock itself is in the isolate).
|
||||
// TODO(svenpanne) This method is on death row...
|
||||
static v8::Isolate* GetDefaultIsolateForLocking();
|
||||
|
||||
private:
|
||||
Isolate();
|
||||
|
||||
@ -1153,10 +1158,6 @@ class Isolate {
|
||||
// If one does not yet exist, allocate a new one.
|
||||
PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
|
||||
|
||||
// PreInits and returns a default isolate. Needed when a new thread tries
|
||||
// to create a Locker for the first time (the lock itself is in the isolate).
|
||||
static Isolate* GetDefaultIsolateForLocking();
|
||||
|
||||
// Initializes the current thread to run this Isolate.
|
||||
// Not thread-safe. Multiple threads should not Enter/Exit the same isolate
|
||||
// at the same time, this should be prevented using external locking.
|
||||
|
@ -42,15 +42,18 @@ namespace v8 {
|
||||
bool Locker::active_ = false;
|
||||
|
||||
|
||||
// Constructor for the Locker object. Once the Locker is constructed the
|
||||
// current thread will be guaranteed to have the lock for a given isolate.
|
||||
Locker::Locker(v8::Isolate* isolate)
|
||||
: has_lock_(false),
|
||||
top_level_(true),
|
||||
isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
|
||||
if (isolate_ == NULL) {
|
||||
isolate_ = i::Isolate::GetDefaultIsolateForLocking();
|
||||
}
|
||||
Locker::Locker() {
|
||||
Initialize(i::Isolate::GetDefaultIsolateForLocking());
|
||||
}
|
||||
|
||||
|
||||
// Once the Locker is initialized, the current thread will be guaranteed to have
|
||||
// the lock for a given isolate.
|
||||
void Locker::Initialize(v8::Isolate* isolate) {
|
||||
ASSERT(isolate != NULL);
|
||||
has_lock_= false;
|
||||
top_level_ = true;
|
||||
isolate_ = reinterpret_cast<i::Isolate*>(isolate);
|
||||
// Record that the Locker has been used at least once.
|
||||
active_ = true;
|
||||
// Get the big lock if necessary.
|
||||
@ -86,10 +89,8 @@ Locker::Locker(v8::Isolate* isolate)
|
||||
|
||||
|
||||
bool Locker::IsLocked(v8::Isolate* isolate) {
|
||||
ASSERT(isolate != NULL);
|
||||
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
if (internal_isolate == NULL) {
|
||||
internal_isolate = i::Isolate::GetDefaultIsolateForLocking();
|
||||
}
|
||||
return internal_isolate->thread_manager()->IsLockedByCurrentThread();
|
||||
}
|
||||
|
||||
@ -115,11 +116,14 @@ Locker::~Locker() {
|
||||
}
|
||||
|
||||
|
||||
Unlocker::Unlocker(v8::Isolate* isolate)
|
||||
: isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
|
||||
if (isolate_ == NULL) {
|
||||
isolate_ = i::Isolate::GetDefaultIsolateForLocking();
|
||||
}
|
||||
Unlocker::Unlocker() {
|
||||
Initialize(i::Isolate::GetDefaultIsolateForLocking());
|
||||
}
|
||||
|
||||
|
||||
void Unlocker::Initialize(v8::Isolate* isolate) {
|
||||
ASSERT(isolate != NULL);
|
||||
isolate_ = reinterpret_cast<i::Isolate*>(isolate);
|
||||
ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
|
||||
if (isolate_->IsDefaultIsolate()) {
|
||||
isolate_->Exit();
|
||||
@ -479,7 +483,7 @@ void ContextSwitcher::Run() {
|
||||
|
||||
// Acknowledge the preemption by the receiving thread.
|
||||
void ContextSwitcher::PreemptionReceived() {
|
||||
ASSERT(Locker::IsLocked());
|
||||
ASSERT(Locker::IsLocked(i::Isolate::GetDefaultIsolateForLocking()));
|
||||
// There is currently no accounting being done for this. But could be in the
|
||||
// future, which is why we leave this in.
|
||||
}
|
||||
|
@ -69,8 +69,12 @@ static void PrintTestList(CcTest* current) {
|
||||
}
|
||||
|
||||
|
||||
v8::Isolate* CcTest::default_isolate_;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
CcTest::set_default_isolate(v8::Isolate::GetCurrent());
|
||||
CHECK(CcTest::default_isolate() != NULL);
|
||||
int tests_run = 0;
|
||||
bool print_run_count = true;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
@ -57,13 +57,17 @@ class CcTest {
|
||||
CcTest(TestFunction* callback, const char* file, const char* name,
|
||||
const char* dependency, bool enabled);
|
||||
void Run() { callback_(); }
|
||||
static int test_count();
|
||||
static CcTest* last() { return last_; }
|
||||
CcTest* prev() { return prev_; }
|
||||
const char* file() { return file_; }
|
||||
const char* name() { return name_; }
|
||||
const char* dependency() { return dependency_; }
|
||||
bool enabled() { return enabled_; }
|
||||
static void set_default_isolate(v8::Isolate* default_isolate) {
|
||||
default_isolate_ = default_isolate;
|
||||
}
|
||||
static v8::Isolate* default_isolate() { return default_isolate_; }
|
||||
|
||||
private:
|
||||
TestFunction* callback_;
|
||||
const char* file_;
|
||||
@ -72,6 +76,7 @@ class CcTest {
|
||||
bool enabled_;
|
||||
static CcTest* last_;
|
||||
CcTest* prev_;
|
||||
static v8::Isolate* default_isolate_;
|
||||
};
|
||||
|
||||
// Switches between all the Api tests using the threading support.
|
||||
@ -87,13 +92,6 @@ class CcTest {
|
||||
class ApiTestFuzzer: public v8::internal::Thread {
|
||||
public:
|
||||
void CallTest();
|
||||
explicit ApiTestFuzzer(int num)
|
||||
: Thread("ApiTestFuzzer"),
|
||||
test_number_(num),
|
||||
gate_(v8::internal::OS::CreateSemaphore(0)),
|
||||
active_(true) {
|
||||
}
|
||||
~ApiTestFuzzer() { delete gate_; }
|
||||
|
||||
// The ApiTestFuzzer is also a Thread, so it has a Run method.
|
||||
virtual void Run();
|
||||
@ -112,6 +110,14 @@ class ApiTestFuzzer: public v8::internal::Thread {
|
||||
static void Fuzz();
|
||||
|
||||
private:
|
||||
explicit ApiTestFuzzer(int num)
|
||||
: Thread("ApiTestFuzzer"),
|
||||
test_number_(num),
|
||||
gate_(v8::internal::OS::CreateSemaphore(0)),
|
||||
active_(true) {
|
||||
}
|
||||
~ApiTestFuzzer() { delete gate_; }
|
||||
|
||||
static bool fuzzing_;
|
||||
static int tests_being_run_;
|
||||
static int current_;
|
||||
|
@ -11017,7 +11017,7 @@ void ApiTestFuzzer::Run() {
|
||||
gate_->Wait();
|
||||
{
|
||||
// ... get the V8 lock and start running the test.
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
CallTest();
|
||||
}
|
||||
// This test finished.
|
||||
@ -11081,7 +11081,7 @@ void ApiTestFuzzer::ContextSwitch() {
|
||||
// If the new thread is the same as the current thread there is nothing to do.
|
||||
if (NextThread()) {
|
||||
// Now it can start.
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(CcTest::default_isolate());
|
||||
// Wait till someone starts us again.
|
||||
gate_->Wait();
|
||||
// And we're off.
|
||||
@ -11133,12 +11133,12 @@ void ApiTestFuzzer::CallTest() {
|
||||
|
||||
|
||||
static v8::Handle<Value> ThrowInJS(const v8::Arguments& args) {
|
||||
CHECK(v8::Locker::IsLocked());
|
||||
CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
ApiTestFuzzer::Fuzz();
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(CcTest::default_isolate());
|
||||
const char* code = "throw 7;";
|
||||
{
|
||||
v8::Locker nested_locker;
|
||||
v8::Locker nested_locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<Value> exception;
|
||||
{ v8::TryCatch try_catch;
|
||||
@ -11156,12 +11156,12 @@ static v8::Handle<Value> ThrowInJS(const v8::Arguments& args) {
|
||||
|
||||
|
||||
static v8::Handle<Value> ThrowInJSNoCatch(const v8::Arguments& args) {
|
||||
CHECK(v8::Locker::IsLocked());
|
||||
CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
ApiTestFuzzer::Fuzz();
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(CcTest::default_isolate());
|
||||
const char* code = "throw 7;";
|
||||
{
|
||||
v8::Locker nested_locker;
|
||||
v8::Locker nested_locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<Value> value = CompileRun(code);
|
||||
CHECK(value.IsEmpty());
|
||||
@ -11173,8 +11173,8 @@ static v8::Handle<Value> ThrowInJSNoCatch(const v8::Arguments& args) {
|
||||
// These are locking tests that don't need to be run again
|
||||
// as part of the locking aggregation tests.
|
||||
TEST(NestedLockers) {
|
||||
v8::Locker locker;
|
||||
CHECK(v8::Locker::IsLocked());
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(ThrowInJS);
|
||||
@ -11195,7 +11195,7 @@ TEST(NestedLockers) {
|
||||
// These are locking tests that don't need to be run again
|
||||
// as part of the locking aggregation tests.
|
||||
TEST(NestedLockersNoTryCatch) {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
Local<v8::FunctionTemplate> fun_templ =
|
||||
@ -11215,24 +11215,24 @@ TEST(NestedLockersNoTryCatch) {
|
||||
|
||||
|
||||
THREADED_TEST(RecursiveLocking) {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
{
|
||||
v8::Locker locker2;
|
||||
CHECK(v8::Locker::IsLocked());
|
||||
v8::Locker locker2(CcTest::default_isolate());
|
||||
CHECK(v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static v8::Handle<Value> UnlockForAMoment(const v8::Arguments& args) {
|
||||
ApiTestFuzzer::Fuzz();
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(CcTest::default_isolate());
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(LockUnlockLock) {
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
Local<v8::FunctionTemplate> fun_templ =
|
||||
@ -11246,7 +11246,7 @@ THREADED_TEST(LockUnlockLock) {
|
||||
CHECK_EQ(42, script->Run()->Int32Value());
|
||||
}
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
Local<v8::FunctionTemplate> fun_templ =
|
||||
@ -12497,7 +12497,7 @@ class RegExpInterruptTest {
|
||||
|
||||
LongRunningRegExp();
|
||||
{
|
||||
v8::Unlocker unlock;
|
||||
v8::Unlocker unlock(CcTest::default_isolate());
|
||||
gc_thread.Join();
|
||||
}
|
||||
v8::Locker::StopPreemption();
|
||||
@ -12524,7 +12524,7 @@ class RegExpInterruptTest {
|
||||
block_->Wait();
|
||||
while (gc_during_regexp_ < kRequiredGCs) {
|
||||
{
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(CcTest::default_isolate());
|
||||
// TODO(lrn): Perhaps create some garbage before collecting.
|
||||
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
|
||||
gc_count_++;
|
||||
@ -12584,7 +12584,7 @@ class RegExpInterruptTest {
|
||||
// Test that a regular expression execution can be interrupted and
|
||||
// survive a garbage collection.
|
||||
TEST(RegExpInterruption) {
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(CcTest::default_isolate());
|
||||
v8::V8::Initialize();
|
||||
v8::HandleScope scope;
|
||||
Local<Context> local_env;
|
||||
@ -12620,7 +12620,7 @@ class ApplyInterruptTest {
|
||||
|
||||
LongRunningApply();
|
||||
{
|
||||
v8::Unlocker unlock;
|
||||
v8::Unlocker unlock(CcTest::default_isolate());
|
||||
gc_thread.Join();
|
||||
}
|
||||
v8::Locker::StopPreemption();
|
||||
@ -12647,7 +12647,7 @@ class ApplyInterruptTest {
|
||||
block_->Wait();
|
||||
while (gc_during_apply_ < kRequiredGCs) {
|
||||
{
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(CcTest::default_isolate());
|
||||
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
|
||||
gc_count_++;
|
||||
}
|
||||
@ -12693,7 +12693,7 @@ class ApplyInterruptTest {
|
||||
// Test that nothing bad happens if we get a preemption just when we were
|
||||
// about to do an apply().
|
||||
TEST(ApplyInterruption) {
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(CcTest::default_isolate());
|
||||
v8::V8::Initialize();
|
||||
v8::HandleScope scope;
|
||||
Local<Context> local_env;
|
||||
@ -12931,7 +12931,7 @@ class RegExpStringModificationTest {
|
||||
v8::Locker::StartPreemption(1);
|
||||
LongRunningRegExp();
|
||||
{
|
||||
v8::Unlocker unlock;
|
||||
v8::Unlocker unlock(CcTest::default_isolate());
|
||||
morph_thread.Join();
|
||||
}
|
||||
v8::Locker::StopPreemption();
|
||||
@ -12960,7 +12960,7 @@ class RegExpStringModificationTest {
|
||||
while (morphs_during_regexp_ < kRequiredModifications &&
|
||||
morphs_ < kMaxModifications) {
|
||||
{
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(CcTest::default_isolate());
|
||||
// Swap string between ascii and two-byte representation.
|
||||
i::String* string = *input_;
|
||||
MorphAString(string, &ascii_resource_, &uc16_resource_);
|
||||
@ -13008,7 +13008,7 @@ class RegExpStringModificationTest {
|
||||
// Test that a regular expression execution can be interrupted and
|
||||
// the string changed without failing.
|
||||
TEST(RegExpStringModification) {
|
||||
v8::Locker lock;
|
||||
v8::Locker lock(CcTest::default_isolate());
|
||||
v8::V8::Initialize();
|
||||
v8::HandleScope scope;
|
||||
Local<Context> local_env;
|
||||
@ -15141,7 +15141,7 @@ TEST(SetResourceConstraints) {
|
||||
TEST(SetResourceConstraintsInThread) {
|
||||
uint32_t* set_limit;
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
static const int K = 1024;
|
||||
set_limit = ComputeStackLimit(128 * K);
|
||||
|
||||
@ -15162,7 +15162,7 @@ TEST(SetResourceConstraintsInThread) {
|
||||
CHECK(stack_limit == set_limit);
|
||||
}
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
CHECK(stack_limit == set_limit);
|
||||
}
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ class LockUnlockLockThread : public JoinableThread {
|
||||
virtual void Run() {
|
||||
v8::Locker lock1(isolate_);
|
||||
CHECK(v8::Locker::IsLocked(isolate_));
|
||||
CHECK(!v8::Locker::IsLocked());
|
||||
CHECK(!v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope;
|
||||
@ -546,13 +546,13 @@ class LockUnlockLockThread : public JoinableThread {
|
||||
{
|
||||
v8::Unlocker unlock1(isolate_);
|
||||
CHECK(!v8::Locker::IsLocked(isolate_));
|
||||
CHECK(!v8::Locker::IsLocked());
|
||||
CHECK(!v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
{
|
||||
v8::Locker lock2(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope;
|
||||
CHECK(v8::Locker::IsLocked(isolate_));
|
||||
CHECK(!v8::Locker::IsLocked());
|
||||
CHECK(!v8::Locker::IsLocked(CcTest::default_isolate()));
|
||||
v8::Context::Scope context_scope(context_);
|
||||
CalcFibAndCheck();
|
||||
}
|
||||
@ -594,16 +594,16 @@ class LockUnlockLockDefaultIsolateThread : public JoinableThread {
|
||||
}
|
||||
|
||||
virtual void Run() {
|
||||
v8::Locker lock1;
|
||||
v8::Locker lock1(CcTest::default_isolate());
|
||||
{
|
||||
v8::HandleScope handle_scope;
|
||||
v8::Context::Scope context_scope(context_);
|
||||
CalcFibAndCheck();
|
||||
}
|
||||
{
|
||||
v8::Unlocker unlock1;
|
||||
v8::Unlocker unlock1(CcTest::default_isolate());
|
||||
{
|
||||
v8::Locker lock2;
|
||||
v8::Locker lock2(CcTest::default_isolate());
|
||||
v8::HandleScope handle_scope;
|
||||
v8::Context::Scope context_scope(context_);
|
||||
CalcFibAndCheck();
|
||||
@ -624,7 +624,7 @@ TEST(LockUnlockLockDefaultIsolateMultithreaded) {
|
||||
#endif
|
||||
Persistent<v8::Context> context;
|
||||
{
|
||||
v8::Locker locker_;
|
||||
v8::Locker locker_(CcTest::default_isolate());
|
||||
v8::HandleScope handle_scope;
|
||||
context = v8::Context::New();
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ class LoopingThread : public v8::internal::Thread {
|
||||
public:
|
||||
LoopingThread() : Thread("LoopingThread") { }
|
||||
void Run() {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
v8_thread_id_ = v8::V8::GetCurrentThreadId();
|
||||
v8::Handle<v8::ObjectTemplate> global =
|
||||
@ -228,7 +228,7 @@ class LoopingThread : public v8::internal::Thread {
|
||||
// from another thread when using Lockers and preemption.
|
||||
TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::V8::Initialize();
|
||||
v8::Locker::StartPreemption(1);
|
||||
semaphore = v8::internal::OS::CreateSemaphore(0);
|
||||
@ -246,7 +246,7 @@ TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
|
||||
semaphore->Wait();
|
||||
}
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
for (int i = 0; i < kThreads; i++) {
|
||||
v8::V8::TerminateExecution(threads[i]->GetV8ThreadId());
|
||||
}
|
||||
@ -256,7 +256,7 @@ TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
|
||||
delete threads[i];
|
||||
}
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::Locker::StopPreemption();
|
||||
}
|
||||
|
||||
@ -372,4 +372,3 @@ TEST(TerminateAndReenterFromThreadItself) {
|
||||
"f()"))->Run()->IsTrue());
|
||||
context.Dispose();
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
TEST(Preemption) {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::V8::Initialize();
|
||||
v8::HandleScope scope;
|
||||
v8::Context::Scope context_scope(v8::Context::New());
|
||||
@ -67,7 +67,7 @@ class ThreadA : public v8::internal::Thread {
|
||||
public:
|
||||
ThreadA() : Thread("ThreadA") { }
|
||||
void Run() {
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
v8::HandleScope scope;
|
||||
v8::Context::Scope context_scope(v8::Context::New());
|
||||
|
||||
@ -86,7 +86,7 @@ class ThreadA : public v8::internal::Thread {
|
||||
turn = CLEAN_CACHE;
|
||||
do {
|
||||
{
|
||||
v8::Unlocker unlocker;
|
||||
v8::Unlocker unlocker(CcTest::default_isolate());
|
||||
Thread::YieldCPU();
|
||||
}
|
||||
} while (turn != SECOND_TIME_FILL_CACHE);
|
||||
@ -105,7 +105,7 @@ class ThreadB : public v8::internal::Thread {
|
||||
void Run() {
|
||||
do {
|
||||
{
|
||||
v8::Locker locker;
|
||||
v8::Locker locker(CcTest::default_isolate());
|
||||
if (turn == CLEAN_CACHE) {
|
||||
v8::HandleScope scope;
|
||||
v8::Context::Scope context_scope(v8::Context::New());
|
||||
|
Loading…
Reference in New Issue
Block a user