summaryrefslogtreecommitdiffstats
path: root/src/top.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/top.cc')
-rw-r--r--src/top.cc161
1 files changed, 86 insertions, 75 deletions
diff --git a/src/top.cc b/src/top.cc
index 1f0d159f..3d86d11b 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -35,10 +35,14 @@
#include "platform.h"
#include "simulator.h"
#include "string-stream.h"
+#include "vm-state-inl.h"
namespace v8 {
namespace internal {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+Semaphore* Top::runtime_profiler_semaphore_ = NULL;
+#endif
ThreadLocalTop Top::thread_local_;
Mutex* Top::break_access_ = OS::CreateMutex();
@@ -74,10 +78,12 @@ void ThreadLocalTop::Initialize() {
#endif
#endif
#ifdef ENABLE_LOGGING_AND_PROFILING
- js_entry_sp_ = 0;
+ js_entry_sp_ = NULL;
+ external_callback_ = NULL;
#endif
#ifdef ENABLE_VMSTATE_TRACKING
- current_vm_state_ = NULL;
+ current_vm_state_ = EXTERNAL;
+ runtime_profiler_state_ = Top::PROF_NOT_IN_JS;
#endif
try_catch_handler_address_ = NULL;
context_ = NULL;
@@ -273,6 +279,11 @@ static bool initialized = false;
void Top::Initialize() {
CHECK(!initialized);
+#ifdef ENABLE_LOGGING_AND_PROFILING
+ ASSERT(runtime_profiler_semaphore_ == NULL);
+ runtime_profiler_semaphore_ = OS::CreateSemaphore(0);
+#endif
+
InitializeThreadLocal();
// Only preallocate on the first initialization.
@@ -290,6 +301,11 @@ void Top::Initialize() {
void Top::TearDown() {
if (initialized) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+ delete runtime_profiler_semaphore_;
+ runtime_profiler_semaphore_ = NULL;
+#endif
+
// Remove the external reference to the preallocated stack memory.
if (preallocated_message_space != NULL) {
delete preallocated_message_space;
@@ -376,79 +392,85 @@ Handle<JSArray> Top::CaptureCurrentStackTrace(
StackTraceFrameIterator it;
int frames_seen = 0;
while (!it.done() && (frames_seen < limit)) {
- // Create a JSObject to hold the information for the StackFrame.
- Handle<JSObject> stackFrame = Factory::NewJSObject(object_function());
-
JavaScriptFrame* frame = it.frame();
- Handle<JSFunction> fun(JSFunction::cast(frame->function()));
- Handle<Script> script(Script::cast(fun->shared()->script()));
-
- if (options & StackTrace::kLineNumber) {
- int script_line_offset = script->line_offset()->value();
- int position = frame->code()->SourcePosition(frame->pc());
- int line_number = GetScriptLineNumber(script, position);
- // line_number is already shifted by the script_line_offset.
- int relative_line_number = line_number - script_line_offset;
- if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
- Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
- int start = (relative_line_number == 0) ? 0 :
- Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
- int column_offset = position - start;
- if (relative_line_number == 0) {
- // For the case where the code is on the same line as the script tag.
- column_offset += script->column_offset()->value();
+
+ List<FrameSummary> frames(3); // Max 2 levels of inlining.
+ 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<JSObject> stackFrame = Factory::NewJSObject(object_function());
+
+ Handle<JSFunction> fun = frames[i].function();
+ Handle<Script> script(Script::cast(fun->shared()->script()));
+
+ if (options & StackTrace::kLineNumber) {
+ int script_line_offset = script->line_offset()->value();
+ int position = frames[i].code()->SourcePosition(frames[i].pc());
+ int line_number = GetScriptLineNumber(script, position);
+ // line_number is already shifted by the script_line_offset.
+ int relative_line_number = line_number - script_line_offset;
+ if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
+ Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
+ int start = (relative_line_number == 0) ? 0 :
+ Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
+ int column_offset = position - start;
+ if (relative_line_number == 0) {
+ // For the case where the code is on the same line as the script
+ // tag.
+ column_offset += script->column_offset()->value();
+ }
+ SetProperty(stackFrame, column_key,
+ Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE);
}
- SetProperty(stackFrame, column_key,
- Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE);
+ SetProperty(stackFrame, line_key,
+ Handle<Smi>(Smi::FromInt(line_number + 1)), NONE);
}
- SetProperty(stackFrame, line_key,
- Handle<Smi>(Smi::FromInt(line_number + 1)), NONE);
- }
- if (options & StackTrace::kScriptName) {
- Handle<Object> script_name(script->name());
- SetProperty(stackFrame, script_key, script_name, NONE);
- }
+ if (options & StackTrace::kScriptName) {
+ Handle<Object> script_name(script->name());
+ SetProperty(stackFrame, script_key, script_name, NONE);
+ }
+
+ if (options & StackTrace::kScriptNameOrSourceURL) {
+ Handle<Object> script_name(script->name());
+ Handle<JSValue> script_wrapper = GetScriptWrapper(script);
+ Handle<Object> property = GetProperty(script_wrapper,
+ name_or_source_url_key);
+ ASSERT(property->IsJSFunction());
+ Handle<JSFunction> method = Handle<JSFunction>::cast(property);
+ bool caught_exception;
+ Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
+ NULL, &caught_exception);
+ if (caught_exception) {
+ result = Factory::undefined_value();
+ }
+ SetProperty(stackFrame, script_name_or_source_url_key, result, NONE);
+ }
- if (options & StackTrace::kScriptNameOrSourceURL) {
- Handle<Object> script_name(script->name());
- Handle<JSValue> script_wrapper = GetScriptWrapper(script);
- Handle<Object> property = GetProperty(script_wrapper,
- name_or_source_url_key);
- ASSERT(property->IsJSFunction());
- Handle<JSFunction> method = Handle<JSFunction>::cast(property);
- bool caught_exception;
- Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
- NULL, &caught_exception);
- if (caught_exception) {
- result = Factory::undefined_value();
+ if (options & StackTrace::kFunctionName) {
+ Handle<Object> fun_name(fun->shared()->name());
+ if (fun_name->ToBoolean()->IsFalse()) {
+ fun_name = Handle<Object>(fun->shared()->inferred_name());
+ }
+ SetProperty(stackFrame, function_key, fun_name, NONE);
}
- SetProperty(stackFrame, script_name_or_source_url_key, result, NONE);
- }
- if (options & StackTrace::kFunctionName) {
- Handle<Object> fun_name(fun->shared()->name());
- if (fun_name->ToBoolean()->IsFalse()) {
- fun_name = Handle<Object>(fun->shared()->inferred_name());
+ if (options & StackTrace::kIsEval) {
+ int type = Smi::cast(script->compilation_type())->value();
+ Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
+ Factory::true_value() : Factory::false_value();
+ SetProperty(stackFrame, eval_key, is_eval, NONE);
}
- SetProperty(stackFrame, function_key, fun_name, NONE);
- }
- if (options & StackTrace::kIsEval) {
- int type = Smi::cast(script->compilation_type())->value();
- Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
- Factory::true_value() : Factory::false_value();
- SetProperty(stackFrame, eval_key, is_eval, NONE);
- }
+ if (options & StackTrace::kIsConstructor) {
+ Handle<Object> is_constructor = (frames[i].is_constructor()) ?
+ Factory::true_value() : Factory::false_value();
+ SetProperty(stackFrame, constructor_key, is_constructor, NONE);
+ }
- if (options & StackTrace::kIsConstructor) {
- Handle<Object> is_constructor = (frame->IsConstructor()) ?
- Factory::true_value() : Factory::false_value();
- SetProperty(stackFrame, constructor_key, is_constructor, NONE);
+ FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
+ frames_seen++;
}
-
- FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
- frames_seen++;
it.Advance();
}
@@ -1079,15 +1101,4 @@ char* Top::RestoreThread(char* from) {
return from + sizeof(thread_local_);
}
-
-ExecutionAccess::ExecutionAccess() {
- Top::break_access_->Lock();
-}
-
-
-ExecutionAccess::~ExecutionAccess() {
- Top::break_access_->Unlock();
-}
-
-
} } // namespace v8::internal