Changed the flags that indicate the status of running vs dead

This allows us to optimized the EnsureInitialized() function
so it doesn't require a function call when we're running

Review URL: http://codereview.chromium.org/113121

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2048 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent dc154a98
...@@ -99,7 +99,6 @@ static i::HandleScopeImplementer thread_local; ...@@ -99,7 +99,6 @@ static i::HandleScopeImplementer thread_local;
// --- E x c e p t i o n B e h a v i o r --- // --- E x c e p t i o n B e h a v i o r ---
static bool has_shut_down = false;
static FatalErrorCallback exception_behavior = NULL; static FatalErrorCallback exception_behavior = NULL;
...@@ -123,7 +122,7 @@ static FatalErrorCallback& GetFatalErrorHandler() { ...@@ -123,7 +122,7 @@ static FatalErrorCallback& GetFatalErrorHandler() {
// When V8 cannot allocated memory FatalProcessOutOfMemory is called. // When V8 cannot allocated memory FatalProcessOutOfMemory is called.
// The default fatal error handler is called and execution is stopped. // The default fatal error handler is called and execution is stopped.
void i::V8::FatalProcessOutOfMemory(const char* location) { void i::V8::FatalProcessOutOfMemory(const char* location) {
has_shut_down = true; i::V8::SetFatalError();
FatalErrorCallback callback = GetFatalErrorHandler(); FatalErrorCallback callback = GetFatalErrorHandler();
{ {
LEAVE_V8; LEAVE_V8;
...@@ -142,13 +141,13 @@ void V8::SetFatalErrorHandler(FatalErrorCallback that) { ...@@ -142,13 +141,13 @@ void V8::SetFatalErrorHandler(FatalErrorCallback that) {
bool Utils::ReportApiFailure(const char* location, const char* message) { bool Utils::ReportApiFailure(const char* location, const char* message) {
FatalErrorCallback callback = GetFatalErrorHandler(); FatalErrorCallback callback = GetFatalErrorHandler();
callback(location, message); callback(location, message);
has_shut_down = true; i::V8::SetFatalError();
return false; return false;
} }
bool V8::IsDead() { bool V8::IsDead() {
return has_shut_down; return i::V8::IsDead();
} }
...@@ -186,7 +185,8 @@ static bool ReportEmptyHandle(const char* location) { ...@@ -186,7 +185,8 @@ static bool ReportEmptyHandle(const char* location) {
* yet been done. * yet been done.
*/ */
static inline bool IsDeadCheck(const char* location) { static inline bool IsDeadCheck(const char* location) {
return has_shut_down ? ReportV8Dead(location) : false; return !i::V8::IsRunning()
&& i::V8::IsDead() ? ReportV8Dead(location) : false;
} }
...@@ -205,9 +205,14 @@ static inline bool EmptyCheck(const char* location, const v8::Data* obj) { ...@@ -205,9 +205,14 @@ static inline bool EmptyCheck(const char* location, const v8::Data* obj) {
static i::StringInputBuffer write_input_buffer; static i::StringInputBuffer write_input_buffer;
static void EnsureInitialized(const char* location) { static inline bool EnsureInitialized(const char* location) {
if (IsDeadCheck(location)) return; if (i::V8::IsRunning()) {
ApiCheck(v8::V8::Initialize(), location, "Error initializing V8"); return true;
}
if (IsDeadCheck(location)) {
return false;
}
return ApiCheck(v8::V8::Initialize(), location, "Error initializing V8");
} }
...@@ -225,29 +230,25 @@ void ImplementationUtilities::ZapHandleRange(void** begin, void** end) { ...@@ -225,29 +230,25 @@ void ImplementationUtilities::ZapHandleRange(void** begin, void** end) {
v8::Handle<v8::Primitive> ImplementationUtilities::Undefined() { v8::Handle<v8::Primitive> ImplementationUtilities::Undefined() {
if (IsDeadCheck("v8::Undefined()")) return v8::Handle<v8::Primitive>(); if (!EnsureInitialized("v8::Undefined()")) return v8::Handle<v8::Primitive>();
EnsureInitialized("v8::Undefined()");
return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::undefined_value())); return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::undefined_value()));
} }
v8::Handle<v8::Primitive> ImplementationUtilities::Null() { v8::Handle<v8::Primitive> ImplementationUtilities::Null() {
if (IsDeadCheck("v8::Null()")) return v8::Handle<v8::Primitive>(); if (!EnsureInitialized("v8::Null()")) return v8::Handle<v8::Primitive>();
EnsureInitialized("v8::Null()");
return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::null_value())); return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::null_value()));
} }
v8::Handle<v8::Boolean> ImplementationUtilities::True() { v8::Handle<v8::Boolean> ImplementationUtilities::True() {
if (IsDeadCheck("v8::True()")) return v8::Handle<v8::Boolean>(); if (!EnsureInitialized("v8::True()")) return v8::Handle<v8::Boolean>();
EnsureInitialized("v8::True()");
return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::true_value())); return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::true_value()));
} }
v8::Handle<v8::Boolean> ImplementationUtilities::False() { v8::Handle<v8::Boolean> ImplementationUtilities::False() {
if (IsDeadCheck("v8::False()")) return v8::Handle<v8::Boolean>(); if (!EnsureInitialized("v8::False()")) return v8::Handle<v8::Boolean>();
EnsureInitialized("v8::False()");
return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::false_value())); return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::false_value()));
} }
...@@ -373,21 +374,21 @@ void V8::ClearWeak(void** obj) { ...@@ -373,21 +374,21 @@ void V8::ClearWeak(void** obj) {
bool V8::IsGlobalNearDeath(void** obj) { bool V8::IsGlobalNearDeath(void** obj) {
LOG_API("IsGlobalNearDeath"); LOG_API("IsGlobalNearDeath");
if (has_shut_down) return false; if (!i::V8::IsRunning()) return false;
return i::GlobalHandles::IsNearDeath(reinterpret_cast<i::Object**>(obj)); return i::GlobalHandles::IsNearDeath(reinterpret_cast<i::Object**>(obj));
} }
bool V8::IsGlobalWeak(void** obj) { bool V8::IsGlobalWeak(void** obj) {
LOG_API("IsGlobalWeak"); LOG_API("IsGlobalWeak");
if (has_shut_down) return false; if (!i::V8::IsRunning()) return false;
return i::GlobalHandles::IsWeak(reinterpret_cast<i::Object**>(obj)); return i::GlobalHandles::IsWeak(reinterpret_cast<i::Object**>(obj));
} }
void V8::DisposeGlobal(void** obj) { void V8::DisposeGlobal(void** obj) {
LOG_API("DisposeGlobal"); LOG_API("DisposeGlobal");
if (has_shut_down) return; if (!i::V8::IsRunning()) return;
i::Object** ptr = reinterpret_cast<i::Object**>(obj); i::Object** ptr = reinterpret_cast<i::Object**>(obj);
if ((*ptr)->IsGlobalContext()) i::Heap::NotifyContextDisposed(); if ((*ptr)->IsGlobalContext()) i::Heap::NotifyContextDisposed();
i::GlobalHandles::Destroy(ptr); i::GlobalHandles::Destroy(ptr);
...@@ -431,7 +432,7 @@ void Context::Enter() { ...@@ -431,7 +432,7 @@ void Context::Enter() {
void Context::Exit() { void Context::Exit() {
if (has_shut_down) return; if (!i::V8::IsRunning()) return;
if (!ApiCheck(thread_local.LeaveLastContext(), if (!ApiCheck(thread_local.LeaveLastContext(),
"v8::Context::Exit()", "v8::Context::Exit()",
"Cannot exit non-entered context")) { "Cannot exit non-entered context")) {
...@@ -2450,7 +2451,7 @@ void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { ...@@ -2450,7 +2451,7 @@ void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
// --- E n v i r o n m e n t --- // --- E n v i r o n m e n t ---
bool v8::V8::Initialize() { bool v8::V8::Initialize() {
if (i::V8::HasBeenSetup()) return true; if (i::V8::IsRunning()) return true;
ENTER_V8; ENTER_V8;
HandleScope scope; HandleScope scope;
if (i::Snapshot::Initialize()) { if (i::Snapshot::Initialize()) {
...@@ -3331,7 +3332,7 @@ bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that, ...@@ -3331,7 +3332,7 @@ bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
void Debug::DebugBreak() { void Debug::DebugBreak() {
if (!i::V8::HasBeenSetup()) return; if (!i::V8::IsRunning()) return;
i::StackGuard::DebugBreak(); i::StackGuard::DebugBreak();
} }
...@@ -3373,7 +3374,7 @@ void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) { ...@@ -3373,7 +3374,7 @@ void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
void Debug::SendCommand(const uint16_t* command, int length, void Debug::SendCommand(const uint16_t* command, int length,
ClientData* client_data) { ClientData* client_data) {
if (!i::V8::HasBeenSetup()) return; if (!i::V8::IsRunning()) return;
i::Debugger::ProcessCommand(i::Vector<const uint16_t>(command, length), i::Debugger::ProcessCommand(i::Vector<const uint16_t>(command, length),
client_data); client_data);
} }
...@@ -3389,7 +3390,7 @@ void Debug::SetHostDispatchHandler(HostDispatchHandler handler, ...@@ -3389,7 +3390,7 @@ void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
Handle<Value> Debug::Call(v8::Handle<v8::Function> fun, Handle<Value> Debug::Call(v8::Handle<v8::Function> fun,
v8::Handle<v8::Value> data) { v8::Handle<v8::Value> data) {
if (!i::V8::HasBeenSetup()) return Handle<Value>(); if (!i::V8::IsRunning()) return Handle<Value>();
ON_BAILOUT("v8::Debug::Call()", return Handle<Value>()); ON_BAILOUT("v8::Debug::Call()", return Handle<Value>());
ENTER_V8; ENTER_V8;
i::Handle<i::Object> result; i::Handle<i::Object> result;
......
...@@ -1530,8 +1530,8 @@ Genesis::Genesis(Handle<Object> global_object, ...@@ -1530,8 +1530,8 @@ Genesis::Genesis(Handle<Object> global_object,
current_ = this; current_ = this;
result_ = NULL; result_ = NULL;
// If V8 hasn't been and cannot be initialized, just return. // If V8 isn't running and cannot be initialized, just return.
if (!V8::HasBeenSetup() && !V8::Initialize(NULL)) return; if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
// Before creating the roots we must save the context and restore it // Before creating the roots we must save the context and restore it
// on all function exits. // on all function exits.
......
...@@ -36,14 +36,20 @@ ...@@ -36,14 +36,20 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
bool V8::is_running_ = false;
bool V8::has_been_setup_ = false; bool V8::has_been_setup_ = false;
bool V8::has_been_disposed_ = false; bool V8::has_been_disposed_ = false;
bool V8::has_fatal_error_ = false;
bool V8::Initialize(Deserializer *des) { bool V8::Initialize(Deserializer *des) {
bool create_heap_objects = des == NULL; bool create_heap_objects = des == NULL;
if (HasBeenDisposed()) return false; if (has_been_disposed_ || has_fatal_error_) return false;
if (HasBeenSetup()) return true; if (IsRunning()) return true;
is_running_ = true;
has_been_setup_ = true; has_been_setup_ = true;
has_fatal_error_ = false;
has_been_disposed_ = false;
#ifdef DEBUG #ifdef DEBUG
// The initialization process does not handle memory exhaustion. // The initialization process does not handle memory exhaustion.
DisallowAllocationFailure disallow_allocation_failure; DisallowAllocationFailure disallow_allocation_failure;
...@@ -59,7 +65,7 @@ bool V8::Initialize(Deserializer *des) { ...@@ -59,7 +65,7 @@ bool V8::Initialize(Deserializer *des) {
// Setup the object heap // Setup the object heap
ASSERT(!Heap::HasBeenSetup()); ASSERT(!Heap::HasBeenSetup());
if (!Heap::Setup(create_heap_objects)) { if (!Heap::Setup(create_heap_objects)) {
has_been_setup_ = false; SetFatalError();
return false; return false;
} }
...@@ -95,9 +101,14 @@ bool V8::Initialize(Deserializer *des) { ...@@ -95,9 +101,14 @@ bool V8::Initialize(Deserializer *des) {
} }
void V8::SetFatalError() {
is_running_ = false;
has_fatal_error_ = true;
}
void V8::TearDown() { void V8::TearDown() {
if (HasBeenDisposed()) return; if (!has_been_setup_ || has_been_disposed_) return;
if (!HasBeenSetup()) return;
OProfileAgent::TearDown(); OProfileAgent::TearDown();
...@@ -114,8 +125,9 @@ void V8::TearDown() { ...@@ -114,8 +125,9 @@ void V8::TearDown() {
Heap::TearDown(); Heap::TearDown();
Logger::TearDown(); Logger::TearDown();
has_been_setup_ = false; is_running_ = false;
has_been_disposed_ = true; has_been_disposed_ = true;
} }
} } // namespace v8::internal } } // namespace v8::internal
...@@ -86,13 +86,23 @@ class V8 : public AllStatic { ...@@ -86,13 +86,23 @@ class V8 : public AllStatic {
// deserialized data into an empty heap. // deserialized data into an empty heap.
static bool Initialize(Deserializer* des); static bool Initialize(Deserializer* des);
static void TearDown(); static void TearDown();
static bool HasBeenSetup() { return has_been_setup_; } static bool IsRunning() { return is_running_; }
static bool HasBeenDisposed() { return has_been_disposed_; } // To be dead you have to have lived
static bool IsDead() { return has_fatal_error_ || has_been_disposed_; }
static void SetFatalError();
// Report process out of memory. Implementation found in api.cc. // Report process out of memory. Implementation found in api.cc.
static void FatalProcessOutOfMemory(const char* location); static void FatalProcessOutOfMemory(const char* location);
private: private:
// True if engine is currently running
static bool is_running_;
// True if V8 has ever been run
static bool has_been_setup_; static bool has_been_setup_;
// True if error has been signaled for current engine
// (reset to false if engine is restarted)
static bool has_fatal_error_;
// True if engine has been shut down
// (reset if engine is restarted)
static bool has_been_disposed_; static bool has_been_disposed_;
}; };
......
...@@ -201,7 +201,7 @@ TEST(ProfLazyMode) { ...@@ -201,7 +201,7 @@ TEST(ProfLazyMode) {
// If tests are being run manually, V8 will be already initialized // If tests are being run manually, V8 will be already initialized
// by the test below. // by the test below.
const bool need_to_set_up_logger = i::V8::HasBeenSetup(); const bool need_to_set_up_logger = i::V8::IsRunning();
v8::HandleScope scope; v8::HandleScope scope;
v8::Handle<v8::Context> env = v8::Context::New(); v8::Handle<v8::Context> env = v8::Context::New();
if (need_to_set_up_logger) Logger::Setup(); if (need_to_set_up_logger) Logger::Setup();
...@@ -620,7 +620,7 @@ TEST(EquivalenceOfLoggingAndTraversal) { ...@@ -620,7 +620,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
// are using V8. // are using V8.
// //
// P.S. No, V8 can't be re-initialized after disposal, see include/v8.h. // P.S. No, V8 can't be re-initialized after disposal, see include/v8.h.
CHECK(!i::V8::HasBeenSetup()); CHECK(!i::V8::IsRunning());
i::FLAG_logfile = "*"; i::FLAG_logfile = "*";
i::FLAG_log = true; i::FLAG_log = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment