| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "bootstrapper.h" | 31 #include "bootstrapper.h" |
| 32 #include "debug.h" | 32 #include "debug.h" |
| 33 #include "execution.h" | 33 #include "execution.h" |
| 34 #include "messages.h" | 34 #include "messages.h" |
| 35 #include "platform.h" | 35 #include "platform.h" |
| 36 #include "simulator.h" | 36 #include "simulator.h" |
| 37 #include "string-stream.h" | 37 #include "string-stream.h" |
| 38 #include "vm-state-inl.h" |
| 39 |
| 40 // TODO(isolates): move to isolate.cc. This stuff is kept here to |
| 41 // simplify merging. |
| 38 | 42 |
| 39 namespace v8 { | 43 namespace v8 { |
| 40 namespace internal { | 44 namespace internal { |
| 41 | 45 |
| 42 | |
| 43 v8::TryCatch* ThreadLocalTop::TryCatchHandler() { | 46 v8::TryCatch* ThreadLocalTop::TryCatchHandler() { |
| 44 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); | 47 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); |
| 45 } | 48 } |
| 46 | 49 |
| 47 | 50 |
| 48 void ThreadLocalTop::Initialize() { | 51 void ThreadLocalTop::Initialize() { |
| 49 c_entry_fp_ = 0; | 52 c_entry_fp_ = 0; |
| 50 handler_ = 0; | 53 handler_ = 0; |
| 51 #ifdef USE_SIMULATOR | 54 #ifdef USE_SIMULATOR |
| 52 #ifdef V8_TARGET_ARCH_ARM | 55 #ifdef V8_TARGET_ARCH_ARM |
| 53 simulator_ = assembler::arm::Simulator::current(Isolate::Current()); | 56 simulator_ = assembler::arm::Simulator::current(Isolate::Current()); |
| 54 #elif V8_TARGET_ARCH_MIPS | 57 #elif V8_TARGET_ARCH_MIPS |
| 55 simulator_ = assembler::mips::Simulator::current(Isolate::Current()); | 58 simulator_ = assembler::mips::Simulator::current(Isolate::Current()); |
| 56 #endif | 59 #endif |
| 57 #endif | 60 #endif |
| 58 #ifdef ENABLE_LOGGING_AND_PROFILING | 61 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 59 js_entry_sp_ = 0; | 62 js_entry_sp_ = NULL; |
| 63 external_callback_ = NULL; |
| 60 #endif | 64 #endif |
| 61 #ifdef ENABLE_VMSTATE_TRACKING | 65 #ifdef ENABLE_VMSTATE_TRACKING |
| 62 current_vm_state_ = NULL; | 66 current_vm_state_ = EXTERNAL; |
| 63 #endif | 67 #endif |
| 64 try_catch_handler_address_ = NULL; | 68 try_catch_handler_address_ = NULL; |
| 65 context_ = NULL; | 69 context_ = NULL; |
| 66 int id = Isolate::Current()->thread_manager()->CurrentId(); | 70 int id = Isolate::Current()->thread_manager()->CurrentId(); |
| 67 thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id; | 71 thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id; |
| 68 external_caught_exception_ = false; | 72 external_caught_exception_ = false; |
| 69 failed_access_check_callback_ = NULL; | 73 failed_access_check_callback_ = NULL; |
| 70 save_context_ = NULL; | 74 save_context_ = NULL; |
| 71 catcher_ = NULL; | 75 catcher_ = NULL; |
| 72 } | 76 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 Handle<String> script_name_or_source_url_key = | 200 Handle<String> script_name_or_source_url_key = |
| 197 factory()->LookupAsciiSymbol("scriptNameOrSourceURL"); | 201 factory()->LookupAsciiSymbol("scriptNameOrSourceURL"); |
| 198 Handle<String> function_key = factory()->LookupAsciiSymbol("functionName"); | 202 Handle<String> function_key = factory()->LookupAsciiSymbol("functionName"); |
| 199 Handle<String> eval_key = factory()->LookupAsciiSymbol("isEval"); | 203 Handle<String> eval_key = factory()->LookupAsciiSymbol("isEval"); |
| 200 Handle<String> constructor_key = | 204 Handle<String> constructor_key = |
| 201 factory()->LookupAsciiSymbol("isConstructor"); | 205 factory()->LookupAsciiSymbol("isConstructor"); |
| 202 | 206 |
| 203 StackTraceFrameIterator it; | 207 StackTraceFrameIterator it; |
| 204 int frames_seen = 0; | 208 int frames_seen = 0; |
| 205 while (!it.done() && (frames_seen < limit)) { | 209 while (!it.done() && (frames_seen < limit)) { |
| 206 // Create a JSObject to hold the information for the StackFrame. | 210 JavaScriptFrame* frame = it.frame(); |
| 207 Handle<JSObject> stackFrame = factory()->NewJSObject(object_function()); | |
| 208 | 211 |
| 209 JavaScriptFrame* frame = it.frame(); | 212 List<FrameSummary> frames(3); // Max 2 levels of inlining. |
| 210 Handle<JSFunction> fun(JSFunction::cast(frame->function())); | 213 frame->Summarize(&frames); |
| 211 Handle<Script> script(Script::cast(fun->shared()->script())); | 214 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
| 215 // Create a JSObject to hold the information for the StackFrame. |
| 216 Handle<JSObject> stackFrame = factory()->NewJSObject(object_function()); |
| 212 | 217 |
| 213 if (options & StackTrace::kLineNumber) { | 218 Handle<JSFunction> fun = frames[i].function(); |
| 214 int script_line_offset = script->line_offset()->value(); | 219 Handle<Script> script(Script::cast(fun->shared()->script())); |
| 215 int position = frame->LookupCode(this)->SourcePosition(frame->pc()); | 220 |
| 216 int line_number = GetScriptLineNumber(script, position); | 221 if (options & StackTrace::kLineNumber) { |
| 217 // line_number is already shifted by the script_line_offset. | 222 int script_line_offset = script->line_offset()->value(); |
| 218 int relative_line_number = line_number - script_line_offset; | 223 int position = frames[i].code()->SourcePosition(frames[i].pc()); |
| 219 if (options & StackTrace::kColumnOffset && relative_line_number >= 0) { | 224 int line_number = GetScriptLineNumber(script, position); |
| 220 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); | 225 // line_number is already shifted by the script_line_offset. |
| 221 int start = (relative_line_number == 0) ? 0 : | 226 int relative_line_number = line_number - script_line_offset; |
| 222 Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1; | 227 if (options & StackTrace::kColumnOffset && relative_line_number >= 0) { |
| 223 int column_offset = position - start; | 228 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); |
| 224 if (relative_line_number == 0) { | 229 int start = (relative_line_number == 0) ? 0 : |
| 225 // For the case where the code is on the same line as the script tag. | 230 Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1; |
| 226 column_offset += script->column_offset()->value(); | 231 int column_offset = position - start; |
| 232 if (relative_line_number == 0) { |
| 233 // For the case where the code is on the same line as the script |
| 234 // tag. |
| 235 column_offset += script->column_offset()->value(); |
| 236 } |
| 237 SetProperty(stackFrame, column_key, |
| 238 Handle<Smi>(Smi::FromInt(column_offset + 1), this), NONE); |
| 227 } | 239 } |
| 228 SetProperty(stackFrame, column_key, | 240 SetProperty(stackFrame, line_key, |
| 229 Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE); | 241 Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE); |
| 230 } | 242 } |
| 231 SetProperty(stackFrame, line_key, | 243 |
| 232 Handle<Smi>(Smi::FromInt(line_number + 1)), NONE); | 244 if (options & StackTrace::kScriptName) { |
| 245 Handle<Object> script_name(script->name(), this); |
| 246 SetProperty(stackFrame, script_key, script_name, NONE); |
| 247 } |
| 248 |
| 249 if (options & StackTrace::kScriptNameOrSourceURL) { |
| 250 Handle<Object> script_name(script->name(), this); |
| 251 Handle<JSValue> script_wrapper = GetScriptWrapper(script); |
| 252 Handle<Object> property = GetProperty(script_wrapper, |
| 253 name_or_source_url_key); |
| 254 ASSERT(property->IsJSFunction()); |
| 255 Handle<JSFunction> method = Handle<JSFunction>::cast(property); |
| 256 bool caught_exception; |
| 257 Handle<Object> result = Execution::TryCall(method, script_wrapper, 0, |
| 258 NULL, &caught_exception); |
| 259 if (caught_exception) { |
| 260 result = factory()->undefined_value(); |
| 261 } |
| 262 SetProperty(stackFrame, script_name_or_source_url_key, result, NONE); |
| 263 } |
| 264 |
| 265 if (options & StackTrace::kFunctionName) { |
| 266 Handle<Object> fun_name(fun->shared()->name(), this); |
| 267 if (fun_name->ToBoolean()->IsFalse()) { |
| 268 fun_name = Handle<Object>(fun->shared()->inferred_name(), this); |
| 269 } |
| 270 SetProperty(stackFrame, function_key, fun_name, NONE); |
| 271 } |
| 272 |
| 273 if (options & StackTrace::kIsEval) { |
| 274 int type = Smi::cast(script->compilation_type())->value(); |
| 275 Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ? |
| 276 factory()->true_value() : factory()->false_value(); |
| 277 SetProperty(stackFrame, eval_key, is_eval, NONE); |
| 278 } |
| 279 |
| 280 if (options & StackTrace::kIsConstructor) { |
| 281 Handle<Object> is_constructor = (frames[i].is_constructor()) ? |
| 282 factory()->true_value() : factory()->false_value(); |
| 283 SetProperty(stackFrame, constructor_key, is_constructor, NONE); |
| 284 } |
| 285 |
| 286 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame); |
| 287 frames_seen++; |
| 233 } | 288 } |
| 234 | |
| 235 if (options & StackTrace::kScriptName) { | |
| 236 Handle<Object> script_name(script->name()); | |
| 237 SetProperty(stackFrame, script_key, script_name, NONE); | |
| 238 } | |
| 239 | |
| 240 if (options & StackTrace::kScriptNameOrSourceURL) { | |
| 241 Handle<Object> script_name(script->name()); | |
| 242 Handle<JSValue> script_wrapper = GetScriptWrapper(script); | |
| 243 Handle<Object> property = GetProperty(script_wrapper, | |
| 244 name_or_source_url_key); | |
| 245 ASSERT(property->IsJSFunction()); | |
| 246 Handle<JSFunction> method = Handle<JSFunction>::cast(property); | |
| 247 bool caught_exception; | |
| 248 Handle<Object> result = Execution::TryCall(method, script_wrapper, 0, | |
| 249 NULL, &caught_exception); | |
| 250 if (caught_exception) { | |
| 251 result = factory()->undefined_value(); | |
| 252 } | |
| 253 SetProperty(stackFrame, script_name_or_source_url_key, result, NONE); | |
| 254 } | |
| 255 | |
| 256 if (options & StackTrace::kFunctionName) { | |
| 257 Handle<Object> fun_name(fun->shared()->name()); | |
| 258 if (fun_name->ToBoolean()->IsFalse()) { | |
| 259 fun_name = Handle<Object>(fun->shared()->inferred_name()); | |
| 260 } | |
| 261 SetProperty(stackFrame, function_key, fun_name, NONE); | |
| 262 } | |
| 263 | |
| 264 if (options & StackTrace::kIsEval) { | |
| 265 int type = Smi::cast(script->compilation_type())->value(); | |
| 266 Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ? | |
| 267 factory()->true_value() : factory()->false_value(); | |
| 268 SetProperty(stackFrame, eval_key, is_eval, NONE); | |
| 269 } | |
| 270 | |
| 271 if (options & StackTrace::kIsConstructor) { | |
| 272 Handle<Object> is_constructor = (frame->IsConstructor()) ? | |
| 273 factory()->true_value() : factory()->false_value(); | |
| 274 SetProperty(stackFrame, constructor_key, is_constructor, NONE); | |
| 275 } | |
| 276 | |
| 277 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame); | |
| 278 frames_seen++; | |
| 279 it.Advance(); | 289 it.Advance(); |
| 280 } | 290 } |
| 281 | 291 |
| 282 stack_trace->set_length(Smi::FromInt(frames_seen)); | 292 stack_trace->set_length(Smi::FromInt(frames_seen)); |
| 283 return stack_trace; | 293 return stack_trace; |
| 284 } | 294 } |
| 285 | 295 |
| 286 | 296 |
| 287 void Isolate::PrintStack() { | 297 void Isolate::PrintStack() { |
| 288 if (stack_trace_nesting_level_ == 0) { | 298 if (stack_trace_nesting_level_ == 0) { |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 } | 893 } |
| 884 #endif // ENABLE_DEBUGGER_SUPPORT | 894 #endif // ENABLE_DEBUGGER_SUPPORT |
| 885 if (it.done()) return Handle<Context>::null(); | 895 if (it.done()) return Handle<Context>::null(); |
| 886 JavaScriptFrame* frame = it.frame(); | 896 JavaScriptFrame* frame = it.frame(); |
| 887 Context* context = Context::cast(frame->context()); | 897 Context* context = Context::cast(frame->context()); |
| 888 return Handle<Context>(context->global_context()); | 898 return Handle<Context>(context->global_context()); |
| 889 } | 899 } |
| 890 | 900 |
| 891 | 901 |
| 892 char* Isolate::ArchiveThread(char* to) { | 902 char* Isolate::ArchiveThread(char* to) { |
| 903 if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) { |
| 904 RuntimeProfiler::IsolateExitedJS(this); |
| 905 } |
| 893 memcpy(to, reinterpret_cast<char*>(thread_local_top()), | 906 memcpy(to, reinterpret_cast<char*>(thread_local_top()), |
| 894 sizeof(ThreadLocalTop)); | 907 sizeof(ThreadLocalTop)); |
| 895 InitializeThreadLocal(); | 908 InitializeThreadLocal(); |
| 896 return to + sizeof(ThreadLocalTop); | 909 return to + sizeof(ThreadLocalTop); |
| 897 } | 910 } |
| 898 | 911 |
| 899 | 912 |
| 900 char* Isolate::RestoreThread(char* from) { | 913 char* Isolate::RestoreThread(char* from) { |
| 901 memcpy(reinterpret_cast<char*>(thread_local_top()), from, | 914 memcpy(reinterpret_cast<char*>(thread_local_top()), from, |
| 902 sizeof(ThreadLocalTop)); | 915 sizeof(ThreadLocalTop)); |
| 903 // This might be just paranoia, but it seems to be needed in case a | 916 // This might be just paranoia, but it seems to be needed in case a |
| 904 // thread_local_ is restored on a separate OS thread. | 917 // thread_local_ is restored on a separate OS thread. |
| 905 #ifdef USE_SIMULATOR | 918 #ifdef USE_SIMULATOR |
| 906 #ifdef V8_TARGET_ARCH_ARM | 919 #ifdef V8_TARGET_ARCH_ARM |
| 907 thread_local_top()->simulator_ = assembler::arm::Simulator::current(this); | 920 thread_local_top()->simulator_ = assembler::arm::Simulator::current(this); |
| 908 #elif V8_TARGET_ARCH_MIPS | 921 #elif V8_TARGET_ARCH_MIPS |
| 909 thread_local_top()->simulator_ = assembler::mips::Simulator::current(this); | 922 thread_local_top()->simulator_ = assembler::mips::Simulator::current(this); |
| 910 #endif | 923 #endif |
| 911 #endif | 924 #endif |
| 925 if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) { |
| 926 RuntimeProfiler::IsolateEnteredJS(this); |
| 927 } |
| 912 return from + sizeof(ThreadLocalTop); | 928 return from + sizeof(ThreadLocalTop); |
| 913 } | 929 } |
| 914 | 930 |
| 915 | |
| 916 ExecutionAccess::ExecutionAccess() { | |
| 917 Isolate::Current()->break_access()->Lock(); | |
| 918 } | |
| 919 | |
| 920 | |
| 921 ExecutionAccess::~ExecutionAccess() { | |
| 922 Isolate::Current()->break_access()->Unlock(); | |
| 923 } | |
| 924 | |
| 925 | |
| 926 } } // namespace v8::internal | 931 } } // namespace v8::internal |
| OLD | NEW |