| Index: src/top.h
|
| ===================================================================
|
| --- src/top.h (revision 7267)
|
| +++ src/top.h (working copy)
|
| @@ -1,608 +0,0 @@
|
| -// Copyright 2006-2008 the V8 project authors. All rights reserved.
|
| -// Redistribution and use in source and binary forms, with or without
|
| -// modification, are permitted provided that the following conditions are
|
| -// met:
|
| -//
|
| -// * Redistributions of source code must retain the above copyright
|
| -// notice, this list of conditions and the following disclaimer.
|
| -// * Redistributions in binary form must reproduce the above
|
| -// copyright notice, this list of conditions and the following
|
| -// disclaimer in the documentation and/or other materials provided
|
| -// with the distribution.
|
| -// * Neither the name of Google Inc. nor the names of its
|
| -// contributors may be used to endorse or promote products derived
|
| -// from this software without specific prior written permission.
|
| -//
|
| -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| -
|
| -#ifndef V8_TOP_H_
|
| -#define V8_TOP_H_
|
| -
|
| -#include "atomicops.h"
|
| -#include "compilation-cache.h"
|
| -#include "frames-inl.h"
|
| -#include "runtime-profiler.h"
|
| -
|
| -namespace v8 {
|
| -namespace internal {
|
| -
|
| -class Simulator;
|
| -
|
| -#define RETURN_IF_SCHEDULED_EXCEPTION() \
|
| - if (Top::has_scheduled_exception()) return Top::PromoteScheduledException()
|
| -
|
| -#define RETURN_IF_EMPTY_HANDLE_VALUE(call, value) \
|
| - if (call.is_null()) { \
|
| - ASSERT(Top::has_pending_exception()); \
|
| - return value; \
|
| - }
|
| -
|
| -#define RETURN_IF_EMPTY_HANDLE(call) \
|
| - RETURN_IF_EMPTY_HANDLE_VALUE(call, Failure::Exception())
|
| -
|
| -// Top has static variables used for JavaScript execution.
|
| -
|
| -class SaveContext; // Forward declaration.
|
| -class ThreadVisitor; // Defined in v8threads.h
|
| -class VMState; // Defined in vm-state.h
|
| -
|
| -class ThreadLocalTop BASE_EMBEDDED {
|
| - public:
|
| - // Initialize the thread data.
|
| - void Initialize();
|
| -
|
| - // Get the top C++ try catch handler or NULL if none are registered.
|
| - //
|
| - // This method is not guarenteed to return an address that can be
|
| - // used for comparison with addresses into the JS stack. If such an
|
| - // address is needed, use try_catch_handler_address.
|
| - v8::TryCatch* TryCatchHandler();
|
| -
|
| - // Get the address of the top C++ try catch handler or NULL if
|
| - // none are registered.
|
| - //
|
| - // This method always returns an address that can be compared to
|
| - // pointers into the JavaScript stack. When running on actual
|
| - // hardware, try_catch_handler_address and TryCatchHandler return
|
| - // the same pointer. When running on a simulator with a separate JS
|
| - // stack, try_catch_handler_address returns a JS stack address that
|
| - // corresponds to the place on the JS stack where the C++ handler
|
| - // would have been if the stack were not separate.
|
| - inline Address try_catch_handler_address() {
|
| - return try_catch_handler_address_;
|
| - }
|
| -
|
| - // Set the address of the top C++ try catch handler.
|
| - inline void set_try_catch_handler_address(Address address) {
|
| - try_catch_handler_address_ = address;
|
| - }
|
| -
|
| - void Free() {
|
| - ASSERT(!has_pending_message_);
|
| - ASSERT(!external_caught_exception_);
|
| - ASSERT(try_catch_handler_address_ == NULL);
|
| - }
|
| -
|
| - // The context where the current execution method is created and for variable
|
| - // lookups.
|
| - Context* context_;
|
| - int thread_id_;
|
| - MaybeObject* pending_exception_;
|
| - bool has_pending_message_;
|
| - const char* pending_message_;
|
| - Object* pending_message_obj_;
|
| - Script* pending_message_script_;
|
| - int pending_message_start_pos_;
|
| - int pending_message_end_pos_;
|
| - // Use a separate value for scheduled exceptions to preserve the
|
| - // invariants that hold about pending_exception. We may want to
|
| - // unify them later.
|
| - MaybeObject* scheduled_exception_;
|
| - bool external_caught_exception_;
|
| - SaveContext* save_context_;
|
| - v8::TryCatch* catcher_;
|
| -
|
| - // Stack.
|
| - Address c_entry_fp_; // the frame pointer of the top c entry frame
|
| - Address handler_; // try-blocks are chained through the stack
|
| -
|
| -#ifdef USE_SIMULATOR
|
| -#ifdef V8_TARGET_ARCH_ARM
|
| - Simulator* simulator_;
|
| -#elif V8_TARGET_ARCH_MIPS
|
| - assembler::mips::Simulator* simulator_;
|
| -#endif
|
| -#endif // USE_SIMULATOR
|
| -
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| - Address js_entry_sp_; // the stack pointer of the bottom js entry frame
|
| - Address external_callback_; // the external callback we're currently in
|
| -#endif
|
| -
|
| -#ifdef ENABLE_VMSTATE_TRACKING
|
| - StateTag current_vm_state_;
|
| -
|
| - // Used for communication with the runtime profiler thread.
|
| - // Possible values are specified in RuntimeProfilerState.
|
| - Atomic32 runtime_profiler_state_;
|
| -#endif
|
| -
|
| - // Generated code scratch locations.
|
| - int32_t formal_count_;
|
| -
|
| - // Call back function to report unsafe JS accesses.
|
| - v8::FailedAccessCheckCallback failed_access_check_callback_;
|
| -
|
| - private:
|
| - Address try_catch_handler_address_;
|
| -};
|
| -
|
| -#define TOP_ADDRESS_LIST(C) \
|
| - C(handler_address) \
|
| - C(c_entry_fp_address) \
|
| - C(context_address) \
|
| - C(pending_exception_address) \
|
| - C(external_caught_exception_address)
|
| -
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| -#define TOP_ADDRESS_LIST_PROF(C) \
|
| - C(js_entry_sp_address)
|
| -#else
|
| -#define TOP_ADDRESS_LIST_PROF(C)
|
| -#endif
|
| -
|
| -
|
| -class Top {
|
| - public:
|
| - enum AddressId {
|
| -#define C(name) k_##name,
|
| - TOP_ADDRESS_LIST(C)
|
| - TOP_ADDRESS_LIST_PROF(C)
|
| -#undef C
|
| - k_top_address_count
|
| - };
|
| -
|
| - static Address get_address_from_id(AddressId id);
|
| -
|
| - // Access to top context (where the current function object was created).
|
| - static Context* context() { return thread_local_.context_; }
|
| - static void set_context(Context* context) {
|
| - thread_local_.context_ = context;
|
| - }
|
| - static Context** context_address() { return &thread_local_.context_; }
|
| -
|
| - static SaveContext* save_context() {return thread_local_.save_context_; }
|
| - static void set_save_context(SaveContext* save) {
|
| - thread_local_.save_context_ = save;
|
| - }
|
| -
|
| - // Access to current thread id.
|
| - static int thread_id() { return thread_local_.thread_id_; }
|
| - static void set_thread_id(int id) { thread_local_.thread_id_ = id; }
|
| -
|
| - // Interface to pending exception.
|
| - static MaybeObject* pending_exception() {
|
| - ASSERT(has_pending_exception());
|
| - return thread_local_.pending_exception_;
|
| - }
|
| - static bool external_caught_exception() {
|
| - return thread_local_.external_caught_exception_;
|
| - }
|
| - static void set_pending_exception(MaybeObject* exception) {
|
| - thread_local_.pending_exception_ = exception;
|
| - }
|
| - static void clear_pending_exception() {
|
| - thread_local_.pending_exception_ = Heap::the_hole_value();
|
| - }
|
| -
|
| - static MaybeObject** pending_exception_address() {
|
| - return &thread_local_.pending_exception_;
|
| - }
|
| - static bool has_pending_exception() {
|
| - return !thread_local_.pending_exception_->IsTheHole();
|
| - }
|
| - static void clear_pending_message() {
|
| - thread_local_.has_pending_message_ = false;
|
| - thread_local_.pending_message_ = NULL;
|
| - thread_local_.pending_message_obj_ = Heap::the_hole_value();
|
| - thread_local_.pending_message_script_ = NULL;
|
| - }
|
| - static v8::TryCatch* try_catch_handler() {
|
| - return thread_local_.TryCatchHandler();
|
| - }
|
| - static Address try_catch_handler_address() {
|
| - return thread_local_.try_catch_handler_address();
|
| - }
|
| - // This method is called by the api after operations that may throw
|
| - // exceptions. If an exception was thrown and not handled by an external
|
| - // handler the exception is scheduled to be rethrown when we return to running
|
| - // JavaScript code. If an exception is scheduled true is returned.
|
| - static bool OptionalRescheduleException(bool is_bottom_call);
|
| -
|
| -
|
| - static bool* external_caught_exception_address() {
|
| - return &thread_local_.external_caught_exception_;
|
| - }
|
| -
|
| - static MaybeObject** scheduled_exception_address() {
|
| - return &thread_local_.scheduled_exception_;
|
| - }
|
| -
|
| - static MaybeObject* scheduled_exception() {
|
| - ASSERT(has_scheduled_exception());
|
| - return thread_local_.scheduled_exception_;
|
| - }
|
| - static bool has_scheduled_exception() {
|
| - return !thread_local_.scheduled_exception_->IsTheHole();
|
| - }
|
| - static void clear_scheduled_exception() {
|
| - thread_local_.scheduled_exception_ = Heap::the_hole_value();
|
| - }
|
| -
|
| - static bool IsExternallyCaught();
|
| -
|
| - static void SetCaptureStackTraceForUncaughtExceptions(
|
| - bool capture,
|
| - int frame_limit,
|
| - StackTrace::StackTraceOptions options);
|
| -
|
| - // Tells whether the current context has experienced an out of memory
|
| - // exception.
|
| - static bool is_out_of_memory();
|
| -
|
| - static bool is_catchable_by_javascript(MaybeObject* exception) {
|
| - return (exception != Failure::OutOfMemoryException()) &&
|
| - (exception != Heap::termination_exception());
|
| - }
|
| -
|
| - // JS execution stack (see frames.h).
|
| - static Address c_entry_fp(ThreadLocalTop* thread) {
|
| - return thread->c_entry_fp_;
|
| - }
|
| - static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
|
| -
|
| - static inline Address* c_entry_fp_address() {
|
| - return &thread_local_.c_entry_fp_;
|
| - }
|
| - static inline Address* handler_address() { return &thread_local_.handler_; }
|
| -
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| - // Bottom JS entry (see StackTracer::Trace in log.cc).
|
| - static Address js_entry_sp(ThreadLocalTop* thread) {
|
| - return thread->js_entry_sp_;
|
| - }
|
| - static inline Address* js_entry_sp_address() {
|
| - return &thread_local_.js_entry_sp_;
|
| - }
|
| -
|
| - static Address external_callback() {
|
| - return thread_local_.external_callback_;
|
| - }
|
| - static void set_external_callback(Address callback) {
|
| - thread_local_.external_callback_ = callback;
|
| - }
|
| -#endif
|
| -
|
| -#ifdef ENABLE_VMSTATE_TRACKING
|
| - static StateTag current_vm_state() {
|
| - return thread_local_.current_vm_state_;
|
| - }
|
| -
|
| - static void SetCurrentVMState(StateTag state) {
|
| - if (RuntimeProfiler::IsEnabled()) {
|
| - if (state == JS) {
|
| - // JS or non-JS -> JS transition.
|
| - RuntimeProfilerState old_state = SwapRuntimeProfilerState(PROF_IN_JS);
|
| - if (old_state == PROF_NOT_IN_JS_WAITING_FOR_JS) {
|
| - // If the runtime profiler was waiting, we reset the eager
|
| - // optimizing data in the compilation cache to get a fresh
|
| - // start after not running JavaScript code for a while and
|
| - // signal the runtime profiler so it can resume.
|
| - CompilationCache::ResetEagerOptimizingData();
|
| - runtime_profiler_semaphore_->Signal();
|
| - }
|
| - } else if (thread_local_.current_vm_state_ == JS) {
|
| - // JS -> non-JS transition. Update the runtime profiler state.
|
| - ASSERT(IsInJSState());
|
| - SetRuntimeProfilerState(PROF_NOT_IN_JS);
|
| - }
|
| - }
|
| - thread_local_.current_vm_state_ = state;
|
| - }
|
| -
|
| - // Called in the runtime profiler thread.
|
| - // Returns whether the current VM state is set to JS.
|
| - static bool IsInJSState() {
|
| - ASSERT(RuntimeProfiler::IsEnabled());
|
| - return static_cast<RuntimeProfilerState>(
|
| - NoBarrier_Load(&thread_local_.runtime_profiler_state_)) == PROF_IN_JS;
|
| - }
|
| -
|
| - // Called in the runtime profiler thread.
|
| - // Waits for the VM state to transtion from non-JS to JS. Returns
|
| - // true when notified of the transition, false when the current
|
| - // state is not the expected non-JS state.
|
| - static bool WaitForJSState() {
|
| - ASSERT(RuntimeProfiler::IsEnabled());
|
| - // Try to switch to waiting state.
|
| - RuntimeProfilerState old_state = CompareAndSwapRuntimeProfilerState(
|
| - PROF_NOT_IN_JS, PROF_NOT_IN_JS_WAITING_FOR_JS);
|
| - if (old_state == PROF_NOT_IN_JS) {
|
| - runtime_profiler_semaphore_->Wait();
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - // When shutting down we join the profiler thread. Doing so while
|
| - // it's waiting on a semaphore will cause a deadlock, so we have to
|
| - // wake it up first.
|
| - static void WakeUpRuntimeProfilerThreadBeforeShutdown() {
|
| - runtime_profiler_semaphore_->Signal();
|
| - }
|
| -#endif
|
| -
|
| - // Generated code scratch locations.
|
| - static void* formal_count_address() { return &thread_local_.formal_count_; }
|
| -
|
| - static void PrintCurrentStackTrace(FILE* out);
|
| - static void PrintStackTrace(FILE* out, char* thread_data);
|
| - static void PrintStack(StringStream* accumulator);
|
| - static void PrintStack();
|
| - static Handle<String> StackTraceString();
|
| - static Handle<JSArray> CaptureCurrentStackTrace(
|
| - int frame_limit,
|
| - StackTrace::StackTraceOptions options);
|
| -
|
| - // Returns if the top context may access the given global object. If
|
| - // the result is false, the pending exception is guaranteed to be
|
| - // set.
|
| - static bool MayNamedAccess(JSObject* receiver,
|
| - Object* key,
|
| - v8::AccessType type);
|
| - static bool MayIndexedAccess(JSObject* receiver,
|
| - uint32_t index,
|
| - v8::AccessType type);
|
| -
|
| - static void SetFailedAccessCheckCallback(
|
| - v8::FailedAccessCheckCallback callback);
|
| - static void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
|
| -
|
| - // Exception throwing support. The caller should use the result
|
| - // of Throw() as its return value.
|
| - static Failure* Throw(Object* exception, MessageLocation* location = NULL);
|
| - // Re-throw an exception. This involves no error reporting since
|
| - // error reporting was handled when the exception was thrown
|
| - // originally.
|
| - static Failure* ReThrow(MaybeObject* exception,
|
| - MessageLocation* location = NULL);
|
| - static void ScheduleThrow(Object* exception);
|
| - static void ReportPendingMessages();
|
| - static Failure* ThrowIllegalOperation();
|
| -
|
| - // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
|
| - static Failure* PromoteScheduledException();
|
| - static void DoThrow(MaybeObject* exception,
|
| - MessageLocation* location,
|
| - const char* message);
|
| - // Checks if exception should be reported and finds out if it's
|
| - // caught externally.
|
| - static bool ShouldReportException(bool* can_be_caught_externally,
|
| - bool catchable_by_javascript);
|
| -
|
| - // Attempts to compute the current source location, storing the
|
| - // result in the target out parameter.
|
| - static void ComputeLocation(MessageLocation* target);
|
| -
|
| - // Override command line flag.
|
| - static void TraceException(bool flag);
|
| -
|
| - // Out of resource exception helpers.
|
| - static Failure* StackOverflow();
|
| - static Failure* TerminateExecution();
|
| -
|
| - // Administration
|
| - static void Initialize();
|
| - static void TearDown();
|
| - static void Iterate(ObjectVisitor* v);
|
| - static void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
|
| - static char* Iterate(ObjectVisitor* v, char* t);
|
| - static void IterateThread(ThreadVisitor* v);
|
| - static void IterateThread(ThreadVisitor* v, char* t);
|
| -
|
| - // Returns the global object of the current context. It could be
|
| - // a builtin object, or a js global object.
|
| - static Handle<GlobalObject> global() {
|
| - return Handle<GlobalObject>(context()->global());
|
| - }
|
| -
|
| - // Returns the global proxy object of the current context.
|
| - static Object* global_proxy() {
|
| - return context()->global_proxy();
|
| - }
|
| -
|
| - // Returns the current global context.
|
| - static Handle<Context> global_context();
|
| -
|
| - // Returns the global context of the calling JavaScript code. That
|
| - // is, the global context of the top-most JavaScript frame.
|
| - static Handle<Context> GetCallingGlobalContext();
|
| -
|
| - static Handle<JSBuiltinsObject> builtins() {
|
| - return Handle<JSBuiltinsObject>(thread_local_.context_->builtins());
|
| - }
|
| -
|
| - static void RegisterTryCatchHandler(v8::TryCatch* that);
|
| - static void UnregisterTryCatchHandler(v8::TryCatch* that);
|
| -
|
| -#define TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR(index, type, name) \
|
| - static Handle<type> name() { \
|
| - return Handle<type>(context()->global_context()->name()); \
|
| - }
|
| - GLOBAL_CONTEXT_FIELDS(TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR)
|
| -#undef TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR
|
| -
|
| - static inline ThreadLocalTop* GetCurrentThread() { return &thread_local_; }
|
| - static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
|
| - static char* ArchiveThread(char* to);
|
| - static char* RestoreThread(char* from);
|
| - static void FreeThreadResources() { thread_local_.Free(); }
|
| -
|
| - static const char* kStackOverflowMessage;
|
| -
|
| - private:
|
| -#ifdef ENABLE_VMSTATE_TRACKING
|
| - // Set of states used when communicating with the runtime profiler.
|
| - //
|
| - // The set of possible transitions is divided between the VM and the
|
| - // profiler threads.
|
| - //
|
| - // The VM thread can perform these transitions:
|
| - // o IN_JS -> NOT_IN_JS
|
| - // o NOT_IN_JS -> IN_JS
|
| - // o NOT_IN_JS_WAITING_FOR_JS -> IN_JS notifying the profiler thread
|
| - // using the semaphore.
|
| - // All the above transitions are caused by VM state changes.
|
| - //
|
| - // The profiler thread can only perform a single transition
|
| - // NOT_IN_JS -> NOT_IN_JS_WAITING_FOR_JS before it starts waiting on
|
| - // the semaphore.
|
| - enum RuntimeProfilerState {
|
| - PROF_NOT_IN_JS,
|
| - PROF_NOT_IN_JS_WAITING_FOR_JS,
|
| - PROF_IN_JS
|
| - };
|
| -
|
| - static void SetRuntimeProfilerState(RuntimeProfilerState state) {
|
| - NoBarrier_Store(&thread_local_.runtime_profiler_state_, state);
|
| - }
|
| -
|
| - static RuntimeProfilerState SwapRuntimeProfilerState(
|
| - RuntimeProfilerState state) {
|
| - return static_cast<RuntimeProfilerState>(
|
| - NoBarrier_AtomicExchange(&thread_local_.runtime_profiler_state_,
|
| - state));
|
| - }
|
| -
|
| - static RuntimeProfilerState CompareAndSwapRuntimeProfilerState(
|
| - RuntimeProfilerState old_state,
|
| - RuntimeProfilerState state) {
|
| - return static_cast<RuntimeProfilerState>(
|
| - NoBarrier_CompareAndSwap(&thread_local_.runtime_profiler_state_,
|
| - old_state,
|
| - state));
|
| - }
|
| -
|
| - static Semaphore* runtime_profiler_semaphore_;
|
| -#endif // ENABLE_VMSTATE_TRACKING
|
| -
|
| - // The context that initiated this JS execution.
|
| - static ThreadLocalTop thread_local_;
|
| - static void InitializeThreadLocal();
|
| - static void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
|
| - static void MarkCompactPrologue(bool is_compacting,
|
| - ThreadLocalTop* archived_thread_data);
|
| - static void MarkCompactEpilogue(bool is_compacting,
|
| - ThreadLocalTop* archived_thread_data);
|
| -
|
| - // Debug.
|
| - // Mutex for serializing access to break control structures.
|
| - static Mutex* break_access_;
|
| -
|
| - friend class SaveContext;
|
| - friend class AssertNoContextChange;
|
| - friend class ExecutionAccess;
|
| - friend class ThreadLocalTop;
|
| -
|
| - static void FillCache();
|
| -};
|
| -
|
| -
|
| -// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
|
| -// class as a work around for a bug in the generated code found with these
|
| -// versions of GCC. See V8 issue 122 for details.
|
| -class SaveContext BASE_EMBEDDED {
|
| - public:
|
| - SaveContext()
|
| - : context_(Top::context()),
|
| -#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
|
| - dummy_(Top::context()),
|
| -#endif
|
| - prev_(Top::save_context()) {
|
| - Top::set_save_context(this);
|
| -
|
| - // If there is no JS frame under the current C frame, use the value 0.
|
| - JavaScriptFrameIterator it;
|
| - js_sp_ = it.done() ? 0 : it.frame()->sp();
|
| - }
|
| -
|
| - ~SaveContext() {
|
| - Top::set_context(*context_);
|
| - Top::set_save_context(prev_);
|
| - }
|
| -
|
| - Handle<Context> context() { return context_; }
|
| - SaveContext* prev() { return prev_; }
|
| -
|
| - // Returns true if this save context is below a given JavaScript frame.
|
| - bool below(JavaScriptFrame* frame) {
|
| - return (js_sp_ == 0) || (frame->sp() < js_sp_);
|
| - }
|
| -
|
| - private:
|
| - Handle<Context> context_;
|
| -#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
|
| - Handle<Context> dummy_;
|
| -#endif
|
| - SaveContext* prev_;
|
| - Address js_sp_; // The top JS frame's sp when saving context.
|
| -};
|
| -
|
| -
|
| -class AssertNoContextChange BASE_EMBEDDED {
|
| -#ifdef DEBUG
|
| - public:
|
| - AssertNoContextChange() :
|
| - context_(Top::context()) {
|
| - }
|
| -
|
| - ~AssertNoContextChange() {
|
| - ASSERT(Top::context() == *context_);
|
| - }
|
| -
|
| - private:
|
| - HandleScope scope_;
|
| - Handle<Context> context_;
|
| -#else
|
| - public:
|
| - AssertNoContextChange() { }
|
| -#endif
|
| -};
|
| -
|
| -
|
| -class ExecutionAccess BASE_EMBEDDED {
|
| - public:
|
| - ExecutionAccess() { Lock(); }
|
| - ~ExecutionAccess() { Unlock(); }
|
| -
|
| - static void Lock() { Top::break_access_->Lock(); }
|
| - static void Unlock() { Top::break_access_->Unlock(); }
|
| -
|
| - static bool TryLock() {
|
| - return Top::break_access_->TryLock();
|
| - }
|
| -};
|
| -
|
| -} } // namespace v8::internal
|
| -
|
| -#endif // V8_TOP_H_
|
|
|