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

Side by Side Diff: src/runtime.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 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 unified diff | Download patch
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2010 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
11 // with the distribution. 11 // with the distribution.
(...skipping 14 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include <stdlib.h> 28 #include <stdlib.h>
29 29
30 #include "v8.h" 30 #include "v8.h"
31 31
32 #include "accessors.h" 32 #include "accessors.h"
33 #include "api.h" 33 #include "api.h"
34 #include "arguments.h" 34 #include "arguments.h"
35 #include "codegen.h" 35 #include "codegen.h"
36 #include "compilation-cache.h"
36 #include "compiler.h" 37 #include "compiler.h"
37 #include "cpu.h" 38 #include "cpu.h"
38 #include "dateparser-inl.h" 39 #include "dateparser-inl.h"
39 #include "debug.h" 40 #include "debug.h"
41 #include "deoptimizer.h"
40 #include "execution.h" 42 #include "execution.h"
41 #include "jsregexp.h" 43 #include "jsregexp.h"
42 #include "liveedit.h" 44 #include "liveedit.h"
43 #include "parser.h" 45 #include "parser.h"
44 #include "platform.h" 46 #include "platform.h"
45 #include "runtime.h" 47 #include "runtime.h"
48 #include "runtime-profiler.h"
46 #include "scopeinfo.h" 49 #include "scopeinfo.h"
47 #include "smart-pointer.h" 50 #include "smart-pointer.h"
48 #include "stub-cache.h" 51 #include "stub-cache.h"
49 #include "v8threads.h" 52 #include "v8threads.h"
50 #include "string-search.h" 53 #include "string-search.h"
51 54
52 namespace v8 { 55 namespace v8 {
53 namespace internal { 56 namespace internal {
54 57
55 58
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 new_proto_map->set_is_hidden_prototype(); 637 new_proto_map->set_is_hidden_prototype();
635 638
636 // Set the object's prototype to proto. 639 // Set the object's prototype to proto.
637 new_map->set_prototype(proto); 640 new_map->set_prototype(proto);
638 jsobject->set_map(new_map); 641 jsobject->set_map(new_map);
639 642
640 return isolate->heap()->undefined_value(); 643 return isolate->heap()->undefined_value();
641 } 644 }
642 645
643 646
647 // Sets the magic number that identifies a function as one of the special
648 // math functions that can be inlined.
649 static MaybeObject* Runtime_SetMathFunctionId(RUNTIME_CALLING_CONVENTION) {
650 RUNTIME_GET_ISOLATE;
651 NoHandleAllocation ha;
652 ASSERT(args.length() == 2);
653 CONVERT_CHECKED(JSFunction, function, args[0]);
654 CONVERT_CHECKED(Smi, id, args[1]);
655 RUNTIME_ASSERT(id->value() >= 0);
656 RUNTIME_ASSERT(id->value() < SharedFunctionInfo::max_math_id_number());
657
658 function->shared()->set_math_function_id(id->value());
659
660 return isolate->heap()->undefined_value();
661 }
662
663
644 static MaybeObject* Runtime_IsConstructCall(RUNTIME_CALLING_CONVENTION) { 664 static MaybeObject* Runtime_IsConstructCall(RUNTIME_CALLING_CONVENTION) {
645 RUNTIME_GET_ISOLATE; 665 RUNTIME_GET_ISOLATE;
646 NoHandleAllocation ha; 666 NoHandleAllocation ha;
647 ASSERT(args.length() == 0); 667 ASSERT(args.length() == 0);
648 JavaScriptFrameIterator it; 668 JavaScriptFrameIterator it;
649 return isolate->heap()->ToBoolean(it.frame()->IsConstructor()); 669 return isolate->heap()->ToBoolean(it.frame()->IsConstructor());
650 } 670 }
651 671
652 672
653 // Recursively traverses hidden prototypes if property is not found 673 // Recursively traverses hidden prototypes if property is not found
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 int pos = fun->shared()->start_position(); 1728 int pos = fun->shared()->start_position();
1709 return Smi::FromInt(pos); 1729 return Smi::FromInt(pos);
1710 } 1730 }
1711 1731
1712 1732
1713 static MaybeObject* Runtime_FunctionGetPositionForOffset( 1733 static MaybeObject* Runtime_FunctionGetPositionForOffset(
1714 RUNTIME_CALLING_CONVENTION) { 1734 RUNTIME_CALLING_CONVENTION) {
1715 RUNTIME_GET_ISOLATE; 1735 RUNTIME_GET_ISOLATE;
1716 ASSERT(args.length() == 2); 1736 ASSERT(args.length() == 2);
1717 1737
1718 CONVERT_CHECKED(JSFunction, fun, args[0]); 1738 CONVERT_CHECKED(Code, code, args[0]);
1719 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); 1739 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
1720 1740
1721 Code* code = fun->code();
1722 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); 1741 RUNTIME_ASSERT(0 <= offset && offset < code->Size());
1723 1742
1724 Address pc = code->address() + offset; 1743 Address pc = code->address() + offset;
1725 return Smi::FromInt(fun->code()->SourcePosition(pc)); 1744 return Smi::FromInt(code->SourcePosition(pc));
1726 } 1745 }
1727 1746
1728 1747
1729 static MaybeObject* Runtime_FunctionSetInstanceClassName( 1748 static MaybeObject* Runtime_FunctionSetInstanceClassName(
1730 RUNTIME_CALLING_CONVENTION) { 1749 RUNTIME_CALLING_CONVENTION) {
1731 RUNTIME_GET_ISOLATE; 1750 RUNTIME_GET_ISOLATE;
1732 NoHandleAllocation ha; 1751 NoHandleAllocation ha;
1733 ASSERT(args.length() == 2); 1752 ASSERT(args.length() == 2);
1734 1753
1735 CONVERT_CHECKED(JSFunction, fun, args[0]); 1754 CONVERT_CHECKED(JSFunction, fun, args[0]);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1800 Handle<Context> context(target->context()); 1819 Handle<Context> context(target->context());
1801 1820
1802 if (!code->IsNull()) { 1821 if (!code->IsNull()) {
1803 RUNTIME_ASSERT(code->IsJSFunction()); 1822 RUNTIME_ASSERT(code->IsJSFunction());
1804 Handle<JSFunction> fun = Handle<JSFunction>::cast(code); 1823 Handle<JSFunction> fun = Handle<JSFunction>::cast(code);
1805 Handle<SharedFunctionInfo> shared(fun->shared()); 1824 Handle<SharedFunctionInfo> shared(fun->shared());
1806 1825
1807 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { 1826 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
1808 return Failure::Exception(); 1827 return Failure::Exception();
1809 } 1828 }
1829 // Since we don't store the source for this we should never
1830 // optimize this.
1831 shared->code()->set_optimizable(false);
1832
1810 // Set the code, scope info, formal parameter count, 1833 // Set the code, scope info, formal parameter count,
1811 // and the length of the target function. 1834 // and the length of the target function.
1812 target->shared()->set_code(shared->code()); 1835 target->shared()->set_code(shared->code());
1813 target->set_code(shared->code()); 1836 target->ReplaceCode(shared->code());
1814 target->shared()->set_scope_info(shared->scope_info()); 1837 target->shared()->set_scope_info(shared->scope_info());
1815 target->shared()->set_length(shared->length()); 1838 target->shared()->set_length(shared->length());
1816 target->shared()->set_formal_parameter_count( 1839 target->shared()->set_formal_parameter_count(
1817 shared->formal_parameter_count()); 1840 shared->formal_parameter_count());
1818 // Set the source code of the target function to undefined. 1841 // Set the source code of the target function to undefined.
1819 // SetCode is only used for built-in constructors like String, 1842 // SetCode is only used for built-in constructors like String,
1820 // Array, and Object, and some web code 1843 // Array, and Object, and some web code
1821 // doesn't like seeing source code for constructors. 1844 // doesn't like seeing source code for constructors.
1822 target->shared()->set_script(isolate->heap()->undefined_value()); 1845 target->shared()->set_script(isolate->heap()->undefined_value());
1823 // Clear the optimization hints related to the compiled code as these are no 1846 // Clear the optimization hints related to the compiled code as these are no
1824 // longer valid when the code is overwritten. 1847 // longer valid when the code is overwritten.
1825 target->shared()->ClearThisPropertyAssignmentsInfo(); 1848 target->shared()->ClearThisPropertyAssignmentsInfo();
1826 context = Handle<Context>(fun->context()); 1849 context = Handle<Context>(fun->context());
1827 1850
1828 // Make sure we get a fresh copy of the literal vector to avoid 1851 // Make sure we get a fresh copy of the literal vector to avoid
1829 // cross context contamination. 1852 // cross context contamination.
1830 int number_of_literals = fun->NumberOfLiterals(); 1853 int number_of_literals = fun->NumberOfLiterals();
1831 Handle<FixedArray> literals = 1854 Handle<FixedArray> literals =
1832 isolate->factory()->NewFixedArray(number_of_literals, TENURED); 1855 isolate->factory()->NewFixedArray(number_of_literals, TENURED);
1833 if (number_of_literals > 0) { 1856 if (number_of_literals > 0) {
1834 // Insert the object, regexp and array functions in the literals 1857 // Insert the object, regexp and array functions in the literals
1835 // array prefix. These are the functions that will be used when 1858 // array prefix. These are the functions that will be used when
1836 // creating object, regexp and array literals. 1859 // creating object, regexp and array literals.
1837 literals->set(JSFunction::kLiteralGlobalContextIndex, 1860 literals->set(JSFunction::kLiteralGlobalContextIndex,
1838 context->global_context()); 1861 context->global_context());
1839 } 1862 }
1840 // It's okay to skip the write barrier here because the literals 1863 // It's okay to skip the write barrier here because the literals
1841 // are guaranteed to be in old space. 1864 // are guaranteed to be in old space.
1842 target->set_literals(*literals, SKIP_WRITE_BARRIER); 1865 target->set_literals(*literals, SKIP_WRITE_BARRIER);
1866 target->set_next_function_link(isolate->heap()->undefined_value());
1843 } 1867 }
1844 1868
1845 target->set_context(*context); 1869 target->set_context(*context);
1846 return *target; 1870 return *target;
1847 } 1871 }
1848 1872
1849 1873
1850 static MaybeObject* Runtime_SetExpectedNumberOfProperties( 1874 static MaybeObject* Runtime_SetExpectedNumberOfProperties(
1851 RUNTIME_CALLING_CONVENTION) { 1875 RUNTIME_CALLING_CONVENTION) {
1852 RUNTIME_GET_ISOLATE; 1876 RUNTIME_GET_ISOLATE;
(...skipping 3716 matching lines...) Expand 10 before | Expand all | Expand 10 after
5569 double value = HeapNumber::cast(obj)->value(); 5593 double value = HeapNumber::cast(obj)->value();
5570 int int_value = FastD2I(value); 5594 int int_value = FastD2I(value);
5571 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { 5595 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
5572 return Smi::FromInt(int_value); 5596 return Smi::FromInt(int_value);
5573 } 5597 }
5574 } 5598 }
5575 return isolate->heap()->nan_value(); 5599 return isolate->heap()->nan_value();
5576 } 5600 }
5577 5601
5578 5602
5603 static MaybeObject* Runtime_AllocateHeapNumber(RUNTIME_CALLING_CONVENTION) {
5604 RUNTIME_GET_ISOLATE;
5605 NoHandleAllocation ha;
5606 ASSERT(args.length() == 0);
5607 return isolate->heap()->AllocateHeapNumber(0);
5608 }
5609
5610
5579 static MaybeObject* Runtime_NumberAdd(RUNTIME_CALLING_CONVENTION) { 5611 static MaybeObject* Runtime_NumberAdd(RUNTIME_CALLING_CONVENTION) {
5580 RUNTIME_GET_ISOLATE; 5612 RUNTIME_GET_ISOLATE;
5581 NoHandleAllocation ha; 5613 NoHandleAllocation ha;
5582 ASSERT(args.length() == 2); 5614 ASSERT(args.length() == 2);
5583 5615
5584 CONVERT_DOUBLE_CHECKED(x, args[0]); 5616 CONVERT_DOUBLE_CHECKED(x, args[0]);
5585 CONVERT_DOUBLE_CHECKED(y, args[1]); 5617 CONVERT_DOUBLE_CHECKED(y, args[1]);
5586 return isolate->heap()->NumberFromDouble(x + y); 5618 return isolate->heap()->NumberFromDouble(x + y);
5587 } 5619 }
5588 5620
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after
6897 // allocate JSFunctions since it does not properly initialize 6929 // allocate JSFunctions since it does not properly initialize
6898 // the shared part of the function. Since the receiver is 6930 // the shared part of the function. Since the receiver is
6899 // ignored anyway, we use the global object as the receiver 6931 // ignored anyway, we use the global object as the receiver
6900 // instead of a new JSFunction object. This way, errors are 6932 // instead of a new JSFunction object. This way, errors are
6901 // reported the same way whether or not 'Function' is called 6933 // reported the same way whether or not 'Function' is called
6902 // using 'new'. 6934 // using 'new'.
6903 return isolate->context()->global(); 6935 return isolate->context()->global();
6904 } 6936 }
6905 } 6937 }
6906 6938
6907 // The function should be compiled for the optimization hints to be available. 6939 // The function should be compiled for the optimization hints to be
6908 Handle<SharedFunctionInfo> shared(function->shared()); 6940 // available. We cannot use EnsureCompiled because that forces a
6909 EnsureCompiled(shared, CLEAR_EXCEPTION); 6941 // compilation through the shared function info which makes it
6942 // impossible for us to optimize.
6943 Handle<SharedFunctionInfo> shared(function->shared(), isolate);
6944 if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION);
6910 6945
6911 if (!function->has_initial_map() && 6946 if (!function->has_initial_map() &&
6912 shared->IsInobjectSlackTrackingInProgress()) { 6947 shared->IsInobjectSlackTrackingInProgress()) {
6913 // The tracking is already in progress for another function. We can only 6948 // The tracking is already in progress for another function. We can only
6914 // track one initial_map at a time, so we force the completion before the 6949 // track one initial_map at a time, so we force the completion before the
6915 // function is called as a constructor for the first time. 6950 // function is called as a constructor for the first time.
6916 shared->CompleteInobjectSlackTracking(); 6951 shared->CompleteInobjectSlackTracking();
6917 } 6952 }
6918 6953
6919 bool first_allocation = !shared->live_objects_may_exist(); 6954 bool first_allocation = !shared->live_objects_may_exist();
(...skipping 25 matching lines...) Expand all
6945 6980
6946 static MaybeObject* Runtime_LazyCompile(RUNTIME_CALLING_CONVENTION) { 6981 static MaybeObject* Runtime_LazyCompile(RUNTIME_CALLING_CONVENTION) {
6947 RUNTIME_GET_ISOLATE; 6982 RUNTIME_GET_ISOLATE;
6948 HandleScope scope(isolate); 6983 HandleScope scope(isolate);
6949 ASSERT(args.length() == 1); 6984 ASSERT(args.length() == 1);
6950 6985
6951 Handle<JSFunction> function = args.at<JSFunction>(0); 6986 Handle<JSFunction> function = args.at<JSFunction>(0);
6952 #ifdef DEBUG 6987 #ifdef DEBUG
6953 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { 6988 if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
6954 PrintF("[lazy: "); 6989 PrintF("[lazy: ");
6955 function->shared()->name()->Print(); 6990 function->PrintName();
6956 PrintF("]\n"); 6991 PrintF("]\n");
6957 } 6992 }
6958 #endif 6993 #endif
6959 6994
6960 // Compile the target function. Here we compile using CompileLazyInLoop in 6995 // Compile the target function. Here we compile using CompileLazyInLoop in
6961 // order to get the optimized version. This helps code like delta-blue 6996 // order to get the optimized version. This helps code like delta-blue
6962 // that calls performance-critical routines through constructors. A 6997 // that calls performance-critical routines through constructors. A
6963 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a 6998 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a
6964 // direct call. Since the in-loop tracking takes place through CallICs 6999 // direct call. Since the in-loop tracking takes place through CallICs
6965 // this means that things called through constructors are never known to 7000 // this means that things called through constructors are never known to
6966 // be in loops. We compile them as if they are in loops here just in case. 7001 // be in loops. We compile them as if they are in loops here just in case.
6967 ASSERT(!function->is_compiled()); 7002 ASSERT(!function->is_compiled());
6968 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { 7003 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) {
6969 return Failure::Exception(); 7004 return Failure::Exception();
6970 } 7005 }
6971 7006
7007 // All done. Return the compiled code.
7008 ASSERT(function->is_compiled());
6972 return function->code(); 7009 return function->code();
6973 } 7010 }
6974 7011
6975 7012
7013 static MaybeObject* Runtime_LazyRecompile(RUNTIME_CALLING_CONVENTION) {
7014 RUNTIME_GET_ISOLATE;
7015 HandleScope scope(isolate);
7016 ASSERT(args.length() == 1);
7017 Handle<JSFunction> function = args.at<JSFunction>(0);
7018 // If the function is not optimizable or debugger is active continue using the
7019 // code from the full compiler.
7020 if (!function->shared()->code()->optimizable() ||
7021 isolate->debug()->has_break_points()) {
7022 function->ReplaceCode(function->shared()->code());
7023 return function->code();
7024 }
7025 if (CompileOptimized(function, AstNode::kNoNumber)) {
7026 return function->code();
7027 }
7028 function->ReplaceCode(function->shared()->code());
7029 return Failure::Exception();
7030 }
7031
7032
7033 static MaybeObject* Runtime_NotifyDeoptimized(RUNTIME_CALLING_CONVENTION) {
7034 RUNTIME_GET_ISOLATE;
7035 HandleScope scope(isolate);
7036 ASSERT(args.length() == 1);
7037 RUNTIME_ASSERT(args[0]->IsSmi());
7038 Deoptimizer::BailoutType type =
7039 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
7040 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
7041 ASSERT(isolate->heap()->IsAllocationAllowed());
7042 int frames = deoptimizer->output_count();
7043
7044 JavaScriptFrameIterator it;
7045 JavaScriptFrame* frame = NULL;
7046 for (int i = 0; i < frames; i++) {
7047 if (i != 0) it.Advance();
7048 frame = it.frame();
7049 deoptimizer->InsertHeapNumberValues(frames - i - 1, frame);
7050 }
7051 delete deoptimizer;
7052
7053 RUNTIME_ASSERT(frame->function()->IsJSFunction());
7054 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
7055 Handle<Object> arguments;
7056 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
7057 if (frame->GetExpression(i) == isolate->heap()->the_hole_value()) {
7058 if (arguments.is_null()) {
7059 // FunctionGetArguments can't throw an exception, so cast away the
7060 // doubt with an assert.
7061 arguments = Handle<Object>(
7062 Accessors::FunctionGetArguments(*function,
7063 NULL)->ToObjectUnchecked());
7064 ASSERT(*arguments != isolate->heap()->null_value());
7065 ASSERT(*arguments != isolate->heap()->undefined_value());
7066 }
7067 frame->SetExpression(i, *arguments);
7068 }
7069 }
7070
7071 isolate->compilation_cache()->MarkForLazyOptimizing(function);
7072 if (type == Deoptimizer::EAGER) {
7073 RUNTIME_ASSERT(function->IsOptimized());
7074 } else {
7075 RUNTIME_ASSERT(!function->IsOptimized());
7076 }
7077
7078 // Avoid doing too much work when running with --always-opt and keep
7079 // the optimized code around.
7080 if (FLAG_always_opt || type == Deoptimizer::LAZY) {
7081 return isolate->heap()->undefined_value();
7082 }
7083
7084 // Count the number of optimized activations of the function.
7085 int activations = 0;
7086 while (!it.done()) {
7087 JavaScriptFrame* frame = it.frame();
7088 if (frame->is_optimized() && frame->function() == *function) {
7089 activations++;
7090 }
7091 it.Advance();
7092 }
7093
7094 // TODO(kasperl): For now, we cannot support removing the optimized
7095 // code when we have recursive invocations of the same function.
7096 if (activations == 0) {
7097 if (FLAG_trace_deopt) {
7098 PrintF("[removing optimized code for: ");
7099 function->PrintName();
7100 PrintF("]\n");
7101 }
7102 function->ReplaceCode(function->shared()->code());
7103 }
7104 return isolate->heap()->undefined_value();
7105 }
7106
7107
7108 static MaybeObject* Runtime_NotifyOSR(RUNTIME_CALLING_CONVENTION) {
7109 RUNTIME_GET_ISOLATE;
7110 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
7111 delete deoptimizer;
7112 return isolate->heap()->undefined_value();
7113 }
7114
7115
7116 static MaybeObject* Runtime_DeoptimizeFunction(RUNTIME_CALLING_CONVENTION) {
7117 RUNTIME_GET_ISOLATE;
7118 HandleScope scope(isolate);
7119 ASSERT(args.length() == 1);
7120 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7121 if (!function->IsOptimized()) return isolate->heap()->undefined_value();
7122
7123 Deoptimizer::DeoptimizeFunction(*function);
7124
7125 return isolate->heap()->undefined_value();
7126 }
7127
7128
7129 static MaybeObject* Runtime_CompileForOnStackReplacement(
7130 RUNTIME_CALLING_CONVENTION) {
7131 RUNTIME_GET_ISOLATE;
7132 HandleScope scope(isolate);
7133 ASSERT(args.length() == 1);
7134 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7135
7136 // We're not prepared to handle a function with arguments object.
7137 ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
7138
7139 // We have hit a back edge in an unoptimized frame for a function that was
7140 // selected for on-stack replacement. Find the unoptimized code object.
7141 Handle<Code> unoptimized(function->shared()->code(), isolate);
7142 // Keep track of whether we've succeeded in optimizing.
7143 bool succeeded = unoptimized->optimizable();
7144 if (succeeded) {
7145 // If we are trying to do OSR when there are already optimized
7146 // activations of the function, it means (a) the function is directly or
7147 // indirectly recursive and (b) an optimized invocation has been
7148 // deoptimized so that we are currently in an unoptimized activation.
7149 // Check for optimized activations of this function.
7150 JavaScriptFrameIterator it;
7151 while (succeeded && !it.done()) {
7152 JavaScriptFrame* frame = it.frame();
7153 succeeded = !frame->is_optimized() || frame->function() != *function;
7154 it.Advance();
7155 }
7156 }
7157
7158 int ast_id = AstNode::kNoNumber;
7159 if (succeeded) {
7160 // The top JS function is this one, the PC is somewhere in the
7161 // unoptimized code.
7162 JavaScriptFrameIterator it;
7163 JavaScriptFrame* frame = it.frame();
7164 ASSERT(frame->function() == *function);
7165 ASSERT(frame->LookupCode(isolate) == *unoptimized);
7166 ASSERT(unoptimized->contains(frame->pc()));
7167
7168 // Use linear search of the unoptimized code's stack check table to find
7169 // the AST id matching the PC.
7170 Address start = unoptimized->instruction_start();
7171 unsigned target_pc_offset = frame->pc() - start;
7172 Address table_cursor = start + unoptimized->stack_check_table_start();
7173 uint32_t table_length = Memory::uint32_at(table_cursor);
7174 table_cursor += kIntSize;
7175 for (unsigned i = 0; i < table_length; ++i) {
7176 // Table entries are (AST id, pc offset) pairs.
7177 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize);
7178 if (pc_offset == target_pc_offset) {
7179 ast_id = static_cast<int>(Memory::uint32_at(table_cursor));
7180 break;
7181 }
7182 table_cursor += 2 * kIntSize;
7183 }
7184 ASSERT(ast_id != AstNode::kNoNumber);
7185 if (FLAG_trace_osr) {
7186 PrintF("[replacing on-stack at AST id %d in ", ast_id);
7187 function->PrintName();
7188 PrintF("]\n");
7189 }
7190
7191 // Try to compile the optimized code. A true return value from
7192 // CompileOptimized means that compilation succeeded, not necessarily
7193 // that optimization succeeded.
7194 if (CompileOptimized(function, ast_id) && function->IsOptimized()) {
7195 DeoptimizationInputData* data = DeoptimizationInputData::cast(
7196 function->code()->deoptimization_data());
7197 if (FLAG_trace_osr) {
7198 PrintF("[on-stack replacement offset %d in optimized code]\n",
7199 data->OsrPcOffset()->value());
7200 }
7201 ASSERT(data->OsrAstId()->value() == ast_id);
7202 ASSERT(data->OsrPcOffset()->value() >= 0);
7203 } else {
7204 succeeded = false;
7205 }
7206 }
7207
7208 // Revert to the original stack checks in the original unoptimized code.
7209 if (FLAG_trace_osr) {
7210 PrintF("[restoring original stack checks in ");
7211 function->PrintName();
7212 PrintF("]\n");
7213 }
7214 StackCheckStub check_stub;
7215 Handle<Code> check_code = check_stub.GetCode();
7216 Handle<Code> replacement_code(
7217 isolate->builtins()->builtin(Builtins::OnStackReplacement));
7218 // Iterate the unoptimized code and revert all the patched stack checks.
7219 for (RelocIterator it(*unoptimized, RelocInfo::kCodeTargetMask);
7220 !it.done();
7221 it.next()) {
7222 RelocInfo* rinfo = it.rinfo();
7223 if (rinfo->target_address() == replacement_code->entry()) {
7224 Deoptimizer::RevertStackCheckCode(rinfo, *check_code);
7225 }
7226 }
7227
7228 // Allow OSR only at nesting level zero again.
7229 unoptimized->set_allow_osr_at_loop_nesting_level(0);
7230
7231 // If the optimization attempt succeeded, return the AST id tagged as a
7232 // smi. This tells the builtin that we need to translate the unoptimized
7233 // frame to an optimized one.
7234 if (succeeded) {
7235 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
7236 return Smi::FromInt(ast_id);
7237 } else {
7238 return Smi::FromInt(-1);
7239 }
7240 }
7241
7242
6976 static MaybeObject* Runtime_GetFunctionDelegate(RUNTIME_CALLING_CONVENTION) { 7243 static MaybeObject* Runtime_GetFunctionDelegate(RUNTIME_CALLING_CONVENTION) {
6977 RUNTIME_GET_ISOLATE; 7244 RUNTIME_GET_ISOLATE;
6978 HandleScope scope(isolate); 7245 HandleScope scope(isolate);
6979 ASSERT(args.length() == 1); 7246 ASSERT(args.length() == 1);
6980 RUNTIME_ASSERT(!args[0]->IsJSFunction()); 7247 RUNTIME_ASSERT(!args[0]->IsJSFunction());
6981 return *Execution::GetFunctionDelegate(args.at<Object>(0)); 7248 return *Execution::GetFunctionDelegate(args.at<Object>(0));
6982 } 7249 }
6983 7250
6984 7251
6985 static MaybeObject* Runtime_GetConstructorDelegate(RUNTIME_CALLING_CONVENTION) { 7252 static MaybeObject* Runtime_GetConstructorDelegate(RUNTIME_CALLING_CONVENTION) {
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
8305 HandleScope scope(isolate); 8572 HandleScope scope(isolate);
8306 CONVERT_ARG_CHECKED(JSObject, array, 0); 8573 CONVERT_ARG_CHECKED(JSObject, array, 0);
8307 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); 8574 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
8308 if (array->elements()->IsDictionary()) { 8575 if (array->elements()->IsDictionary()) {
8309 // Create an array and get all the keys into it, then remove all the 8576 // Create an array and get all the keys into it, then remove all the
8310 // keys that are not integers in the range 0 to length-1. 8577 // keys that are not integers in the range 0 to length-1.
8311 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); 8578 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS);
8312 int keys_length = keys->length(); 8579 int keys_length = keys->length();
8313 for (int i = 0; i < keys_length; i++) { 8580 for (int i = 0; i < keys_length; i++) {
8314 Object* key = keys->get(i); 8581 Object* key = keys->get(i);
8315 uint32_t index; 8582 uint32_t index = 0;
8316 if (!key->ToArrayIndex(&index) || index >= length) { 8583 if (!key->ToArrayIndex(&index) || index >= length) {
8317 // Zap invalid keys. 8584 // Zap invalid keys.
8318 keys->set_undefined(i); 8585 keys->set_undefined(i);
8319 } 8586 }
8320 } 8587 }
8321 return *isolate->factory()->NewJSArrayWithElements(keys); 8588 return *isolate->factory()->NewJSArrayWithElements(keys);
8322 } else { 8589 } else {
8323 ASSERT(array->HasFastElements()); 8590 ASSERT(array->HasFastElements());
8324 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); 8591 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
8325 // -1 means start of array. 8592 // -1 means start of array.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
8439 } 8706 }
8440 return value; 8707 return value;
8441 case CONSTANT_FUNCTION: 8708 case CONSTANT_FUNCTION:
8442 return result->GetConstantFunction(); 8709 return result->GetConstantFunction();
8443 case CALLBACKS: { 8710 case CALLBACKS: {
8444 Object* structure = result->GetCallbackObject(); 8711 Object* structure = result->GetCallbackObject();
8445 if (structure->IsProxy() || structure->IsAccessorInfo()) { 8712 if (structure->IsProxy() || structure->IsAccessorInfo()) {
8446 MaybeObject* maybe_value = receiver->GetPropertyWithCallback( 8713 MaybeObject* maybe_value = receiver->GetPropertyWithCallback(
8447 receiver, structure, name, result->holder()); 8714 receiver, structure, name, result->holder());
8448 if (!maybe_value->ToObject(&value)) { 8715 if (!maybe_value->ToObject(&value)) {
8716 if (maybe_value->IsRetryAfterGC()) return maybe_value;
8449 ASSERT(maybe_value->IsException()); 8717 ASSERT(maybe_value->IsException());
8450 maybe_value = heap->isolate()->pending_exception(); 8718 maybe_value = heap->isolate()->pending_exception();
8451 heap->isolate()->clear_pending_exception(); 8719 heap->isolate()->clear_pending_exception();
8452 if (caught_exception != NULL) { 8720 if (caught_exception != NULL) {
8453 *caught_exception = true; 8721 *caught_exception = true;
8454 } 8722 }
8455 return maybe_value; 8723 return maybe_value;
8456 } 8724 }
8457 return value; 8725 return value;
8458 } else { 8726 } else {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
8759 return heap->undefined_value(); 9027 return heap->undefined_value();
8760 } 9028 }
8761 int count = 0; 9029 int count = 0;
8762 JavaScriptFrameIterator it(id); 9030 JavaScriptFrameIterator it(id);
8763 for (; !it.done(); it.Advance()) { 9031 for (; !it.done(); it.Advance()) {
8764 if (count == index) break; 9032 if (count == index) break;
8765 count++; 9033 count++;
8766 } 9034 }
8767 if (it.done()) return heap->undefined_value(); 9035 if (it.done()) return heap->undefined_value();
8768 9036
9037 bool is_optimized_frame =
9038 it.frame()->LookupCode(isolate)->kind() == Code::OPTIMIZED_FUNCTION;
9039
8769 // Traverse the saved contexts chain to find the active context for the 9040 // Traverse the saved contexts chain to find the active context for the
8770 // selected frame. 9041 // selected frame.
8771 SaveContext* save = isolate->save_context(); 9042 SaveContext* save = isolate->save_context();
8772 while (save != NULL && !save->below(it.frame())) { 9043 while (save != NULL && !save->below(it.frame())) {
8773 save = save->prev(); 9044 save = save->prev();
8774 } 9045 }
8775 ASSERT(save != NULL); 9046 ASSERT(save != NULL);
8776 9047
8777 // Get the frame id. 9048 // Get the frame id.
8778 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); 9049 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
(...skipping 13 matching lines...) Expand all
8792 // Get the context. 9063 // Get the context.
8793 Handle<Context> context(Context::cast(it.frame()->context())); 9064 Handle<Context> context(Context::cast(it.frame()->context()));
8794 9065
8795 // Get the locals names and values into a temporary array. 9066 // Get the locals names and values into a temporary array.
8796 // 9067 //
8797 // TODO(1240907): Hide compiler-introduced stack variables 9068 // TODO(1240907): Hide compiler-introduced stack variables
8798 // (e.g. .result)? For users of the debugger, they will probably be 9069 // (e.g. .result)? For users of the debugger, they will probably be
8799 // confusing. 9070 // confusing.
8800 Handle<FixedArray> locals = 9071 Handle<FixedArray> locals =
8801 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); 9072 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
9073
9074 // Fill in the names of the locals.
8802 for (int i = 0; i < info.NumberOfLocals(); i++) { 9075 for (int i = 0; i < info.NumberOfLocals(); i++) {
8803 // Name of the local.
8804 locals->set(i * 2, *info.LocalName(i)); 9076 locals->set(i * 2, *info.LocalName(i));
9077 }
8805 9078
8806 // Fetch the value of the local - either from the stack or from a 9079 // Fill in the values of the locals.
8807 // heap-allocated context. 9080 for (int i = 0; i < info.NumberOfLocals(); i++) {
8808 if (i < info.number_of_stack_slots()) { 9081 if (is_optimized_frame) {
9082 // If we are inspecting an optimized frame use undefined as the
9083 // value for all locals.
9084 //
9085 // TODO(3141533): We should be able to get the correct values
9086 // for locals in optimized frames.
9087 locals->set(i * 2 + 1, isolate->heap()->undefined_value());
9088 } else if (i < info.number_of_stack_slots()) {
9089 // Get the value from the stack.
8809 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); 9090 locals->set(i * 2 + 1, it.frame()->GetExpression(i));
8810 } else { 9091 } else {
8811 Handle<String> name = info.LocalName(i);
8812 // Traverse the context chain to the function context as all local 9092 // Traverse the context chain to the function context as all local
8813 // variables stored in the context will be on the function context. 9093 // variables stored in the context will be on the function context.
9094 Handle<String> name = info.LocalName(i);
8814 while (!context->is_function_context()) { 9095 while (!context->is_function_context()) {
8815 context = Handle<Context>(context->previous()); 9096 context = Handle<Context>(context->previous());
8816 } 9097 }
8817 ASSERT(context->is_function_context()); 9098 ASSERT(context->is_function_context());
8818 locals->set(i * 2 + 1, 9099 locals->set(i * 2 + 1,
8819 context->get(scope_info->ContextSlotIndex(*name, NULL))); 9100 context->get(scope_info->ContextSlotIndex(*name, NULL)));
8820 } 9101 }
8821 } 9102 }
8822 9103
8823 // Check whether this frame is positioned at return. 9104 // Check whether this frame is positioned at return. If not top
8824 int at_return = (index == 0) ? 9105 // frame or if the frame is optimized it cannot be at a return.
8825 isolate->debug()->IsBreakAtReturn(it.frame()) : false; 9106 bool at_return = false;
9107 if (!is_optimized_frame && index == 0) {
9108 at_return = isolate->debug()->IsBreakAtReturn(it.frame());
9109 }
8826 9110
8827 // If positioned just before return find the value to be returned and add it 9111 // If positioned just before return find the value to be returned and add it
8828 // to the frame information. 9112 // to the frame information.
8829 Handle<Object> return_value = isolate->factory()->undefined_value(); 9113 Handle<Object> return_value = isolate->factory()->undefined_value();
8830 if (at_return) { 9114 if (at_return) {
8831 StackFrameIterator it2; 9115 StackFrameIterator it2;
8832 Address internal_frame_sp = NULL; 9116 Address internal_frame_sp = NULL;
8833 while (!it2.done()) { 9117 while (!it2.done()) {
8834 if (it2.frame()->is_internal()) { 9118 if (it2.frame()->is_internal()) {
8835 internal_frame_sp = it2.frame()->sp(); 9119 internal_frame_sp = it2.frame()->sp();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
8911 9195
8912 // Add arguments name and value. 9196 // Add arguments name and value.
8913 for (int i = 0; i < argument_count; i++) { 9197 for (int i = 0; i < argument_count; i++) {
8914 // Name of the argument. 9198 // Name of the argument.
8915 if (i < info.number_of_parameters()) { 9199 if (i < info.number_of_parameters()) {
8916 details->set(details_index++, *info.parameter_name(i)); 9200 details->set(details_index++, *info.parameter_name(i));
8917 } else { 9201 } else {
8918 details->set(details_index++, heap->undefined_value()); 9202 details->set(details_index++, heap->undefined_value());
8919 } 9203 }
8920 9204
8921 // Parameter value. 9205 // Parameter value. If we are inspecting an optimized frame, use
8922 if (i < it.frame()->GetProvidedParametersCount()) { 9206 // undefined as the value.
9207 //
9208 // TODO(3141533): We should be able to get the actual parameter
9209 // value for optimized frames.
9210 if (!is_optimized_frame &&
9211 (i < it.frame()->GetProvidedParametersCount())) {
8923 details->set(details_index++, it.frame()->GetParameter(i)); 9212 details->set(details_index++, it.frame()->GetParameter(i));
8924 } else { 9213 } else {
8925 details->set(details_index++, heap->undefined_value()); 9214 details->set(details_index++, heap->undefined_value());
8926 } 9215 }
8927 } 9216 }
8928 9217
8929 // Add locals name and value from the temporary copy from the function frame. 9218 // Add locals name and value from the temporary copy from the function frame.
8930 for (int i = 0; i < info.NumberOfLocals() * 2; i++) { 9219 for (int i = 0; i < info.NumberOfLocals() * 2; i++) {
8931 details->set(details_index++, locals->get(i)); 9220 details->set(details_index++, locals->get(i));
8932 } 9221 }
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
9531 return Smi::FromInt(source_position); 9820 return Smi::FromInt(source_position);
9532 } 9821 }
9533 9822
9534 9823
9535 Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, 9824 Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
9536 Handle<Script> script, 9825 Handle<Script> script,
9537 int position) { 9826 int position) {
9538 // Iterate the heap looking for SharedFunctionInfo generated from the 9827 // Iterate the heap looking for SharedFunctionInfo generated from the
9539 // script. The inner most SharedFunctionInfo containing the source position 9828 // script. The inner most SharedFunctionInfo containing the source position
9540 // for the requested break point is found. 9829 // for the requested break point is found.
9541 // NOTE: This might reqire several heap iterations. If the SharedFunctionInfo 9830 // NOTE: This might require several heap iterations. If the SharedFunctionInfo
9542 // which is found is not compiled it is compiled and the heap is iterated 9831 // which is found is not compiled it is compiled and the heap is iterated
9543 // again as the compilation might create inner functions from the newly 9832 // again as the compilation might create inner functions from the newly
9544 // compiled function and the actual requested break point might be in one of 9833 // compiled function and the actual requested break point might be in one of
9545 // these functions. 9834 // these functions.
9546 bool done = false; 9835 bool done = false;
9547 // The current candidate for the source position: 9836 // The current candidate for the source position:
9548 int target_start_position = RelocInfo::kNoPosition; 9837 int target_start_position = RelocInfo::kNoPosition;
9549 Handle<SharedFunctionInfo> target; 9838 Handle<SharedFunctionInfo> target;
9550 while (!done) { 9839 while (!done) {
9551 HeapIterator iterator; 9840 HeapIterator iterator;
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
10388 old_script_name); 10677 old_script_name);
10389 10678
10390 if (old_script->IsScript()) { 10679 if (old_script->IsScript()) {
10391 Handle<Script> script_handle(Script::cast(old_script)); 10680 Handle<Script> script_handle(Script::cast(old_script));
10392 return *(GetScriptWrapper(script_handle)); 10681 return *(GetScriptWrapper(script_handle));
10393 } else { 10682 } else {
10394 return isolate->heap()->null_value(); 10683 return isolate->heap()->null_value();
10395 } 10684 }
10396 } 10685 }
10397 10686
10687
10688 static MaybeObject* Runtime_LiveEditFunctionSourceUpdated(
10689 RUNTIME_CALLING_CONVENTION) {
10690 RUNTIME_GET_ISOLATE;
10691 ASSERT(args.length() == 1);
10692 HandleScope scope(isolate);
10693 CONVERT_ARG_CHECKED(JSArray, shared_info, 0);
10694 return LiveEdit::FunctionSourceUpdated(shared_info);
10695 }
10696
10697
10398 // Replaces code of SharedFunctionInfo with a new one. 10698 // Replaces code of SharedFunctionInfo with a new one.
10399 static MaybeObject* Runtime_LiveEditReplaceFunctionCode( 10699 static MaybeObject* Runtime_LiveEditReplaceFunctionCode(
10400 RUNTIME_CALLING_CONVENTION) { 10700 RUNTIME_CALLING_CONVENTION) {
10401 RUNTIME_GET_ISOLATE; 10701 RUNTIME_GET_ISOLATE;
10402 ASSERT(args.length() == 2); 10702 ASSERT(args.length() == 2);
10403 HandleScope scope(isolate); 10703 HandleScope scope(isolate);
10404 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); 10704 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0);
10405 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); 10705 CONVERT_ARG_CHECKED(JSArray, shared_info, 1);
10406 10706
10407 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); 10707 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
10501 // A testing entry. Returns statement position which is the closest to 10801 // A testing entry. Returns statement position which is the closest to
10502 // source_position. 10802 // source_position.
10503 static MaybeObject* Runtime_GetFunctionCodePositionFromSource( 10803 static MaybeObject* Runtime_GetFunctionCodePositionFromSource(
10504 RUNTIME_CALLING_CONVENTION) { 10804 RUNTIME_CALLING_CONVENTION) {
10505 RUNTIME_GET_ISOLATE; 10805 RUNTIME_GET_ISOLATE;
10506 ASSERT(args.length() == 2); 10806 ASSERT(args.length() == 2);
10507 HandleScope scope(isolate); 10807 HandleScope scope(isolate);
10508 CONVERT_ARG_CHECKED(JSFunction, function, 0); 10808 CONVERT_ARG_CHECKED(JSFunction, function, 0);
10509 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); 10809 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
10510 10810
10511 Handle<Code> code(function->code()); 10811 Handle<Code> code(function->code(), isolate);
10812
10813 if (code->kind() != Code::FUNCTION &&
10814 code->kind() != Code::OPTIMIZED_FUNCTION) {
10815 return isolate->heap()->undefined_value();
10816 }
10512 10817
10513 RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION)); 10818 RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
10514 int closest_pc = 0; 10819 int closest_pc = 0;
10515 int distance = kMaxInt; 10820 int distance = kMaxInt;
10516 while (!it.done()) { 10821 while (!it.done()) {
10517 int statement_position = static_cast<int>(it.rinfo()->data()); 10822 int statement_position = static_cast<int>(it.rinfo()->data());
10518 // Check if this break point is closer that what was previously found. 10823 // Check if this break point is closer that what was previously found.
10519 if (source_position <= statement_position && 10824 if (source_position <= statement_position &&
10520 statement_position - source_position < distance) { 10825 statement_position - source_position < distance) {
10521 closest_pc = 10826 closest_pc =
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
10661 return false; 10966 return false;
10662 } 10967 }
10663 // Skip all frames until we've seen the caller. Also, skip the most 10968 // Skip all frames until we've seen the caller. Also, skip the most
10664 // obvious builtin calls. Some builtin calls (such as Number.ADD 10969 // obvious builtin calls. Some builtin calls (such as Number.ADD
10665 // which is invoked using 'call') are very difficult to recognize 10970 // which is invoked using 'call') are very difficult to recognize
10666 // so we're leaving them in for now. 10971 // so we're leaving them in for now.
10667 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); 10972 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
10668 } 10973 }
10669 10974
10670 10975
10671 // Collect the raw data for a stack trace. Returns an array of three 10976 // Collect the raw data for a stack trace. Returns an array of 4
10672 // element segments each containing a receiver, function and native 10977 // element segments each containing a receiver, function, code and
10673 // code offset. 10978 // native code offset.
10674 static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) { 10979 static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) {
10675 RUNTIME_GET_ISOLATE; 10980 RUNTIME_GET_ISOLATE;
10676 ASSERT_EQ(args.length(), 2); 10981 ASSERT_EQ(args.length(), 2);
10677 Handle<Object> caller = args.at<Object>(0); 10982 Handle<Object> caller = args.at<Object>(0);
10678 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); 10983 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]);
10679 10984
10680 HandleScope scope(isolate); 10985 HandleScope scope(isolate);
10681 10986
10682 limit = Max(limit, 0); // Ensure that limit is not negative. 10987 limit = Max(limit, 0); // Ensure that limit is not negative.
10683 int initial_size = Min(limit, 10); 10988 int initial_size = Min(limit, 10);
10684 Handle<JSArray> result = isolate->factory()->NewJSArray(initial_size * 3); 10989 Handle<JSArray> result = isolate->factory()->NewJSArray(initial_size * 4);
10685 10990
10686 StackFrameIterator iter; 10991 StackFrameIterator iter;
10687 // If the caller parameter is a function we skip frames until we're 10992 // If the caller parameter is a function we skip frames until we're
10688 // under it before starting to collect. 10993 // under it before starting to collect.
10689 bool seen_caller = !caller->IsJSFunction(); 10994 bool seen_caller = !caller->IsJSFunction();
10690 int cursor = 0; 10995 int cursor = 0;
10691 int frames_seen = 0; 10996 int frames_seen = 0;
10692 while (!iter.done() && frames_seen < limit) { 10997 while (!iter.done() && frames_seen < limit) {
10693 StackFrame* raw_frame = iter.frame(); 10998 StackFrame* raw_frame = iter.frame();
10694 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { 10999 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) {
10695 frames_seen++; 11000 frames_seen++;
10696 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); 11001 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
10697 Object* recv = frame->receiver(); 11002 List<FrameSummary> frames(3); // Max 2 levels of inlining.
10698 Object* fun = frame->function(); 11003 frame->Summarize(&frames);
10699 Address pc = frame->pc(); 11004 for (int i = frames.length() - 1; i >= 0; i--) {
10700 Address start = frame->LookupCode(isolate)->address(); 11005 Handle<Object> recv = frames[i].receiver();
10701 Smi* offset = Smi::FromInt(static_cast<int>(pc - start)); 11006 Handle<JSFunction> fun = frames[i].function();
10702 FixedArray* elements = FixedArray::cast(result->elements()); 11007 Handle<Code> code = frames[i].code();
10703 if (cursor + 2 < elements->length()) { 11008 Handle<Smi> offset(Smi::FromInt(frames[i].offset()));
10704 elements->set(cursor++, recv); 11009 FixedArray* elements = FixedArray::cast(result->elements());
10705 elements->set(cursor++, fun); 11010 if (cursor + 3 < elements->length()) {
10706 elements->set(cursor++, offset); 11011 elements->set(cursor++, *recv);
10707 } else { 11012 elements->set(cursor++, *fun);
10708 HandleScope scope(isolate); 11013 elements->set(cursor++, *code);
10709 Handle<Object> recv_handle(recv, isolate); 11014 elements->set(cursor++, *offset);
10710 Handle<Object> fun_handle(fun, isolate); 11015 } else {
10711 SetElement(result, cursor++, recv_handle); 11016 SetElement(result, cursor++, recv);
10712 SetElement(result, cursor++, fun_handle); 11017 SetElement(result, cursor++, fun);
10713 SetElement(result, cursor++, Handle<Smi>(offset)); 11018 SetElement(result, cursor++, code);
11019 SetElement(result, cursor++, offset);
11020 }
10714 } 11021 }
10715 } 11022 }
10716 iter.Advance(); 11023 iter.Advance();
10717 } 11024 }
10718 11025
10719 result->set_length(Smi::FromInt(cursor)); 11026 result->set_length(Smi::FromInt(cursor));
10720 return *result; 11027 return *result;
10721 } 11028 }
10722 11029
10723 11030
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
10963 } else { 11270 } else {
10964 // Handle last resort GC and make sure to allow future allocations 11271 // Handle last resort GC and make sure to allow future allocations
10965 // to grow the heap without causing GCs (if possible). 11272 // to grow the heap without causing GCs (if possible).
10966 COUNTERS->gc_last_resort_from_js()->Increment(); 11273 COUNTERS->gc_last_resort_from_js()->Increment();
10967 HEAP->CollectAllGarbage(false); 11274 HEAP->CollectAllGarbage(false);
10968 } 11275 }
10969 } 11276 }
10970 11277
10971 11278
10972 } } // namespace v8::internal 11279 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698