Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(474)

Unified Diff: src/top.h

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/token.cc ('k') | src/top.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_
« no previous file with comments | « src/token.cc ('k') | src/top.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698