OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 12858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12869 | 12869 |
12870 CONVERT_ARG_CHECKED(String, script_name, 0); | 12870 CONVERT_ARG_CHECKED(String, script_name, 0); |
12871 | 12871 |
12872 // Find the requested script. | 12872 // Find the requested script. |
12873 Handle<Object> result = | 12873 Handle<Object> result = |
12874 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); | 12874 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); |
12875 return *result; | 12875 return *result; |
12876 } | 12876 } |
12877 | 12877 |
12878 | 12878 |
12879 // Determines whether the given stack frame should be displayed in | |
12880 // a stack trace. The caller is the error constructor that asked | |
12881 // for the stack trace to be collected. The first time a construct | |
12882 // call to this function is encountered it is skipped. The seen_caller | |
12883 // in/out parameter is used to remember if the caller has been seen | |
12884 // yet. | |
12885 static bool ShowFrameInStackTrace(StackFrame* raw_frame, | |
12886 Object* caller, | |
12887 bool* seen_caller) { | |
12888 // Only display JS frames. | |
12889 if (!raw_frame->is_java_script()) { | |
12890 return false; | |
12891 } | |
12892 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | |
12893 Object* raw_fun = frame->function(); | |
12894 // Not sure when this can happen but skip it just in case. | |
12895 if (!raw_fun->IsJSFunction()) { | |
12896 return false; | |
12897 } | |
12898 if ((raw_fun == caller) && !(*seen_caller)) { | |
12899 *seen_caller = true; | |
12900 return false; | |
12901 } | |
12902 // Skip all frames until we've seen the caller. | |
12903 if (!(*seen_caller)) return false; | |
12904 // Also, skip non-visible built-in functions and any call with the builtins | |
12905 // object as receiver, so as to not reveal either the builtins object or | |
12906 // an internal function. | |
12907 // The --builtins-in-stack-traces command line flag allows including | |
12908 // internal call sites in the stack trace for debugging purposes. | |
12909 if (!FLAG_builtins_in_stack_traces) { | |
12910 JSFunction* fun = JSFunction::cast(raw_fun); | |
12911 if (frame->receiver()->IsJSBuiltinsObject() || | |
12912 (fun->IsBuiltin() && !fun->shared()->native())) { | |
12913 return false; | |
12914 } | |
12915 } | |
12916 return true; | |
12917 } | |
12918 | |
12919 | |
12920 // Collect the raw data for a stack trace. Returns an array of 4 | 12879 // Collect the raw data for a stack trace. Returns an array of 4 |
12921 // element segments each containing a receiver, function, code and | 12880 // element segments each containing a receiver, function, code and |
12922 // native code offset. | 12881 // native code offset. |
12923 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) { | 12882 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) { |
12924 ASSERT_EQ(args.length(), 3); | 12883 ASSERT_EQ(args.length(), 3); |
12925 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); | 12884 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); |
12926 Handle<Object> caller = args.at<Object>(1); | 12885 Handle<Object> caller = args.at<Object>(1); |
12927 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); | 12886 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); |
12928 | 12887 |
12929 HandleScope scope(isolate); | 12888 HandleScope scope(isolate); |
12930 Factory* factory = isolate->factory(); | 12889 // Optionally capture a more detailed stack trace for the message. |
12931 | 12890 isolate->CaptureAndSetDetailedStackTrace(error_object); |
12932 limit = Max(limit, 0); // Ensure that limit is not negative. | 12891 // Capture a simple stack trace for the stack property. |
12933 int initial_size = Min(limit, 10); | 12892 return *isolate->CaptureSimpleStackTrace(error_object, caller, limit); |
12934 Handle<FixedArray> elements = | |
12935 factory->NewFixedArrayWithHoles(initial_size * 4); | |
12936 | |
12937 StackFrameIterator iter(isolate); | |
12938 // If the caller parameter is a function we skip frames until we're | |
12939 // under it before starting to collect. | |
12940 bool seen_caller = !caller->IsJSFunction(); | |
12941 int cursor = 0; | |
12942 int frames_seen = 0; | |
12943 while (!iter.done() && frames_seen < limit) { | |
12944 StackFrame* raw_frame = iter.frame(); | |
12945 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { | |
12946 frames_seen++; | |
12947 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | |
12948 // Set initial size to the maximum inlining level + 1 for the outermost | |
12949 // function. | |
12950 List<FrameSummary> frames(Compiler::kMaxInliningLevels + 1); | |
12951 frame->Summarize(&frames); | |
12952 for (int i = frames.length() - 1; i >= 0; i--) { | |
12953 if (cursor + 4 > elements->length()) { | |
12954 int new_capacity = JSObject::NewElementsCapacity(elements->length()); | |
12955 Handle<FixedArray> new_elements = | |
12956 factory->NewFixedArrayWithHoles(new_capacity); | |
12957 for (int i = 0; i < cursor; i++) { | |
12958 new_elements->set(i, elements->get(i)); | |
12959 } | |
12960 elements = new_elements; | |
12961 } | |
12962 ASSERT(cursor + 4 <= elements->length()); | |
12963 | |
12964 Handle<Object> recv = frames[i].receiver(); | |
12965 Handle<JSFunction> fun = frames[i].function(); | |
12966 Handle<Code> code = frames[i].code(); | |
12967 Handle<Smi> offset(Smi::FromInt(frames[i].offset())); | |
12968 elements->set(cursor++, *recv); | |
12969 elements->set(cursor++, *fun); | |
12970 elements->set(cursor++, *code); | |
12971 elements->set(cursor++, *offset); | |
12972 } | |
12973 } | |
12974 iter.Advance(); | |
12975 } | |
12976 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); | |
12977 // Capture and attach a more detailed stack trace if necessary. | |
12978 isolate->CaptureAndSetCurrentStackTraceFor(error_object); | |
12979 result->set_length(Smi::FromInt(cursor)); | |
12980 return *result; | |
12981 } | 12893 } |
12982 | 12894 |
12983 | 12895 |
| 12896 // Retrieve the raw stack trace collected on stack overflow and delete |
| 12897 // it since it is used only once to avoid keeping it alive. |
| 12898 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedRawStackTrace) { |
| 12899 ASSERT_EQ(args.length(), 1); |
| 12900 CONVERT_ARG_CHECKED(JSObject, error_object, 0); |
| 12901 String* key = isolate->heap()->hidden_stack_trace_symbol(); |
| 12902 Object* result = error_object->GetHiddenProperty(key); |
| 12903 RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined()); |
| 12904 error_object->DeleteHiddenProperty(key); |
| 12905 return result; |
| 12906 } |
| 12907 |
| 12908 |
12984 // Returns V8 version as a string. | 12909 // Returns V8 version as a string. |
12985 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { | 12910 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { |
12986 ASSERT_EQ(args.length(), 0); | 12911 ASSERT_EQ(args.length(), 0); |
12987 | 12912 |
12988 NoHandleAllocation ha; | 12913 NoHandleAllocation ha; |
12989 | 12914 |
12990 const char* version_string = v8::V8::GetVersion(); | 12915 const char* version_string = v8::V8::GetVersion(); |
12991 | 12916 |
12992 return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string), | 12917 return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string), |
12993 NOT_TENURED); | 12918 NOT_TENURED); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13364 // Handle last resort GC and make sure to allow future allocations | 13289 // Handle last resort GC and make sure to allow future allocations |
13365 // to grow the heap without causing GCs (if possible). | 13290 // to grow the heap without causing GCs (if possible). |
13366 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13291 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13367 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13292 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13368 "Runtime::PerformGC"); | 13293 "Runtime::PerformGC"); |
13369 } | 13294 } |
13370 } | 13295 } |
13371 | 13296 |
13372 | 13297 |
13373 } } // namespace v8::internal | 13298 } } // namespace v8::internal |
OLD | NEW |