From: vitalyr@chromium.org Date: Fri, 13 May 2011 08:54:16 +0000 (+0000) Subject: Isolates cleanup: move top.cc to isolate.cc. X-Git-Tag: upstream/4.7.83~19417 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=73c809bb0e4672cfafc495b6fc0930e3992b44f0;p=platform%2Fupstream%2Fv8.git Isolates cleanup: move top.cc to isolate.cc. Review URL: http://codereview.chromium.org/6969042 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7884 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/SConscript b/src/SConscript index 5ebc1cc..7ad864c 100755 --- a/src/SConscript +++ b/src/SConscript @@ -122,7 +122,6 @@ SOURCES = { strtod.cc stub-cache.cc token.cc - top.cc type-info.cc unicode.cc utils.cc diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 0b01b8b..aa1d274 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -327,7 +327,7 @@ DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator (4 or 8, 8 is default)") -// top.cc +// isolate.cc DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, diff --git a/src/isolate.cc b/src/isolate.cc index 4871702..9fac06a 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -40,6 +40,7 @@ #include "isolate.h" #include "lithium-allocator.h" #include "log.h" +#include "messages.h" #include "regexp-stack.h" #include "runtime-profiler.h" #include "scanner.h" @@ -49,6 +50,7 @@ #include "spaces.h" #include "stub-cache.h" #include "version.h" +#include "vm-state-inl.h" namespace v8 { @@ -61,6 +63,7 @@ int ThreadId::AllocateThreadId() { return new_id; } + int ThreadId::GetCurrentThreadId() { int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_); if (thread_id == 0) { @@ -70,6 +73,53 @@ int ThreadId::GetCurrentThreadId() { return thread_id; } + +ThreadLocalTop::ThreadLocalTop() { + InitializeInternal(); +} + + +void ThreadLocalTop::InitializeInternal() { + c_entry_fp_ = 0; + handler_ = 0; +#ifdef USE_SIMULATOR + simulator_ = NULL; +#endif +#ifdef ENABLE_LOGGING_AND_PROFILING + js_entry_sp_ = NULL; + external_callback_ = NULL; +#endif +#ifdef ENABLE_VMSTATE_TRACKING + current_vm_state_ = EXTERNAL; +#endif + try_catch_handler_address_ = NULL; + context_ = NULL; + thread_id_ = ThreadId::Invalid(); + external_caught_exception_ = false; + failed_access_check_callback_ = NULL; + save_context_ = NULL; + catcher_ = NULL; +} + + +void ThreadLocalTop::Initialize() { + InitializeInternal(); +#ifdef USE_SIMULATOR +#ifdef V8_TARGET_ARCH_ARM + simulator_ = Simulator::current(isolate_); +#elif V8_TARGET_ARCH_MIPS + simulator_ = Simulator::current(isolate_); +#endif +#endif + thread_id_ = ThreadId::Current(); +} + + +v8::TryCatch* ThreadLocalTop::TryCatchHandler() { + return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); +} + + // Create a dummy thread that will wait forever on a semaphore. The only // purpose for this thread is to have some stack area to save essential data // into for use by a stacks only core dump (aka minidump). @@ -372,6 +422,890 @@ Isolate* Isolate::GetDefaultIsolateForLocking() { } +Address Isolate::get_address_from_id(Isolate::AddressId id) { + return isolate_addresses_[id]; +} + + +char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) { + ThreadLocalTop* thread = reinterpret_cast(thread_storage); + Iterate(v, thread); + return thread_storage + sizeof(ThreadLocalTop); +} + + +void Isolate::IterateThread(ThreadVisitor* v) { + v->VisitThread(this, thread_local_top()); +} + + +void Isolate::IterateThread(ThreadVisitor* v, char* t) { + ThreadLocalTop* thread = reinterpret_cast(t); + v->VisitThread(this, thread); +} + + +void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { + // Visit the roots from the top for a given thread. + Object* pending; + // The pending exception can sometimes be a failure. We can't show + // that to the GC, which only understands objects. + if (thread->pending_exception_->ToObject(&pending)) { + v->VisitPointer(&pending); + thread->pending_exception_ = pending; // In case GC updated it. + } + v->VisitPointer(&(thread->pending_message_obj_)); + v->VisitPointer(BitCast(&(thread->pending_message_script_))); + v->VisitPointer(BitCast(&(thread->context_))); + Object* scheduled; + if (thread->scheduled_exception_->ToObject(&scheduled)) { + v->VisitPointer(&scheduled); + thread->scheduled_exception_ = scheduled; + } + + for (v8::TryCatch* block = thread->TryCatchHandler(); + block != NULL; + block = TRY_CATCH_FROM_ADDRESS(block->next_)) { + v->VisitPointer(BitCast(&(block->exception_))); + v->VisitPointer(BitCast(&(block->message_))); + } + + // Iterate over pointers on native execution stack. + for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) { + it.frame()->Iterate(v); + } +} + + +void Isolate::Iterate(ObjectVisitor* v) { + ThreadLocalTop* current_t = thread_local_top(); + Iterate(v, current_t); +} + + +void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) { + // The ARM simulator has a separate JS stack. We therefore register + // the C++ try catch handler with the simulator and get back an + // address that can be used for comparisons with addresses into the + // JS stack. When running without the simulator, the address + // returned will be the address of the C++ try catch handler itself. + Address address = reinterpret_cast
( + SimulatorStack::RegisterCTryCatch(reinterpret_cast(that))); + thread_local_top()->set_try_catch_handler_address(address); +} + + +void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) { + ASSERT(thread_local_top()->TryCatchHandler() == that); + thread_local_top()->set_try_catch_handler_address( + reinterpret_cast
(that->next_)); + thread_local_top()->catcher_ = NULL; + SimulatorStack::UnregisterCTryCatch(); +} + + +Handle Isolate::StackTraceString() { + if (stack_trace_nesting_level_ == 0) { + stack_trace_nesting_level_++; + HeapStringAllocator allocator; + StringStream::ClearMentionedObjectCache(); + StringStream accumulator(&allocator); + incomplete_message_ = &accumulator; + PrintStack(&accumulator); + Handle stack_trace = accumulator.ToString(); + incomplete_message_ = NULL; + stack_trace_nesting_level_ = 0; + return stack_trace; + } else if (stack_trace_nesting_level_ == 1) { + stack_trace_nesting_level_++; + OS::PrintError( + "\n\nAttempt to print stack while printing stack (double fault)\n"); + OS::PrintError( + "If you are lucky you may find a partial stack dump on stdout.\n\n"); + incomplete_message_->OutputToStdOut(); + return factory()->empty_symbol(); + } else { + OS::Abort(); + // Unreachable + return factory()->empty_symbol(); + } +} + + +Handle Isolate::CaptureCurrentStackTrace( + int frame_limit, StackTrace::StackTraceOptions options) { + // Ensure no negative values. + int limit = Max(frame_limit, 0); + Handle stack_trace = factory()->NewJSArray(frame_limit); + + Handle column_key = factory()->LookupAsciiSymbol("column"); + Handle line_key = factory()->LookupAsciiSymbol("lineNumber"); + Handle script_key = factory()->LookupAsciiSymbol("scriptName"); + Handle name_or_source_url_key = + factory()->LookupAsciiSymbol("nameOrSourceURL"); + Handle script_name_or_source_url_key = + factory()->LookupAsciiSymbol("scriptNameOrSourceURL"); + Handle function_key = factory()->LookupAsciiSymbol("functionName"); + Handle eval_key = factory()->LookupAsciiSymbol("isEval"); + Handle constructor_key = + factory()->LookupAsciiSymbol("isConstructor"); + + StackTraceFrameIterator it(this); + int frames_seen = 0; + while (!it.done() && (frames_seen < limit)) { + JavaScriptFrame* frame = it.frame(); + // Set initial size to the maximum inlining level + 1 for the outermost + // function. + List frames(Compiler::kMaxInliningLevels + 1); + frame->Summarize(&frames); + for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { + // Create a JSObject to hold the information for the StackFrame. + Handle stackFrame = factory()->NewJSObject(object_function()); + + Handle fun = frames[i].function(); + Handle