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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index e0785793fec68df1a6581f221ba6495202c41315..3c40896f742cf8bd23de10f79f6e5f9ad73fabc0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -33,16 +33,19 @@
#include "api.h"
#include "arguments.h"
#include "codegen.h"
+#include "compilation-cache.h"
#include "compiler.h"
#include "cpu.h"
#include "dateparser-inl.h"
#include "debug.h"
+#include "deoptimizer.h"
#include "execution.h"
#include "jsregexp.h"
#include "liveedit.h"
#include "parser.h"
#include "platform.h"
#include "runtime.h"
+#include "runtime-profiler.h"
#include "scopeinfo.h"
#include "smart-pointer.h"
#include "stub-cache.h"
@@ -641,6 +644,23 @@ static MaybeObject* Runtime_SetHiddenPrototype(RUNTIME_CALLING_CONVENTION) {
}
+// Sets the magic number that identifies a function as one of the special
+// math functions that can be inlined.
+static MaybeObject* Runtime_SetMathFunctionId(RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 2);
+ CONVERT_CHECKED(JSFunction, function, args[0]);
+ CONVERT_CHECKED(Smi, id, args[1]);
+ RUNTIME_ASSERT(id->value() >= 0);
+ RUNTIME_ASSERT(id->value() < SharedFunctionInfo::max_math_id_number());
+
+ function->shared()->set_math_function_id(id->value());
+
+ return isolate->heap()->undefined_value();
+}
+
+
static MaybeObject* Runtime_IsConstructCall(RUNTIME_CALLING_CONVENTION) {
RUNTIME_GET_ISOLATE;
NoHandleAllocation ha;
@@ -1715,14 +1735,13 @@ static MaybeObject* Runtime_FunctionGetPositionForOffset(
RUNTIME_GET_ISOLATE;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSFunction, fun, args[0]);
+ CONVERT_CHECKED(Code, code, args[0]);
CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
- Code* code = fun->code();
RUNTIME_ASSERT(0 <= offset && offset < code->Size());
Address pc = code->address() + offset;
- return Smi::FromInt(fun->code()->SourcePosition(pc));
+ return Smi::FromInt(code->SourcePosition(pc));
}
@@ -1807,10 +1826,14 @@ static MaybeObject* Runtime_SetCode(RUNTIME_CALLING_CONVENTION) {
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
return Failure::Exception();
}
+ // Since we don't store the source for this we should never
+ // optimize this.
+ shared->code()->set_optimizable(false);
+
// Set the code, scope info, formal parameter count,
// and the length of the target function.
target->shared()->set_code(shared->code());
- target->set_code(shared->code());
+ target->ReplaceCode(shared->code());
target->shared()->set_scope_info(shared->scope_info());
target->shared()->set_length(shared->length());
target->shared()->set_formal_parameter_count(
@@ -1840,6 +1863,7 @@ static MaybeObject* Runtime_SetCode(RUNTIME_CALLING_CONVENTION) {
// It's okay to skip the write barrier here because the literals
// are guaranteed to be in old space.
target->set_literals(*literals, SKIP_WRITE_BARRIER);
+ target->set_next_function_link(isolate->heap()->undefined_value());
}
target->set_context(*context);
@@ -5576,6 +5600,14 @@ static MaybeObject* Runtime_NumberToSmi(RUNTIME_CALLING_CONVENTION) {
}
+static MaybeObject* Runtime_AllocateHeapNumber(RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 0);
+ return isolate->heap()->AllocateHeapNumber(0);
+}
+
+
static MaybeObject* Runtime_NumberAdd(RUNTIME_CALLING_CONVENTION) {
RUNTIME_GET_ISOLATE;
NoHandleAllocation ha;
@@ -6904,9 +6936,12 @@ static MaybeObject* Runtime_NewObject(RUNTIME_CALLING_CONVENTION) {
}
}
- // The function should be compiled for the optimization hints to be available.
- Handle<SharedFunctionInfo> shared(function->shared());
- EnsureCompiled(shared, CLEAR_EXCEPTION);
+ // The function should be compiled for the optimization hints to be
+ // available. We cannot use EnsureCompiled because that forces a
+ // compilation through the shared function info which makes it
+ // impossible for us to optimize.
+ Handle<SharedFunctionInfo> shared(function->shared(), isolate);
+ if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION);
if (!function->has_initial_map() &&
shared->IsInobjectSlackTrackingInProgress()) {
@@ -6952,7 +6987,7 @@ static MaybeObject* Runtime_LazyCompile(RUNTIME_CALLING_CONVENTION) {
#ifdef DEBUG
if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
PrintF("[lazy: ");
- function->shared()->name()->Print();
+ function->PrintName();
PrintF("]\n");
}
#endif
@@ -6969,10 +7004,242 @@ static MaybeObject* Runtime_LazyCompile(RUNTIME_CALLING_CONVENTION) {
return Failure::Exception();
}
+ // All done. Return the compiled code.
+ ASSERT(function->is_compiled());
return function->code();
}
+static MaybeObject* Runtime_LazyRecompile(RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ Handle<JSFunction> function = args.at<JSFunction>(0);
+ // If the function is not optimizable or debugger is active continue using the
+ // code from the full compiler.
+ if (!function->shared()->code()->optimizable() ||
+ isolate->debug()->has_break_points()) {
+ function->ReplaceCode(function->shared()->code());
+ return function->code();
+ }
+ if (CompileOptimized(function, AstNode::kNoNumber)) {
+ return function->code();
+ }
+ function->ReplaceCode(function->shared()->code());
+ return Failure::Exception();
+}
+
+
+static MaybeObject* Runtime_NotifyDeoptimized(RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ RUNTIME_ASSERT(args[0]->IsSmi());
+ Deoptimizer::BailoutType type =
+ static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
+ Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
+ ASSERT(isolate->heap()->IsAllocationAllowed());
+ int frames = deoptimizer->output_count();
+
+ JavaScriptFrameIterator it;
+ JavaScriptFrame* frame = NULL;
+ for (int i = 0; i < frames; i++) {
+ if (i != 0) it.Advance();
+ frame = it.frame();
+ deoptimizer->InsertHeapNumberValues(frames - i - 1, frame);
+ }
+ delete deoptimizer;
+
+ RUNTIME_ASSERT(frame->function()->IsJSFunction());
+ Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
+ Handle<Object> arguments;
+ for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
+ if (frame->GetExpression(i) == isolate->heap()->the_hole_value()) {
+ if (arguments.is_null()) {
+ // FunctionGetArguments can't throw an exception, so cast away the
+ // doubt with an assert.
+ arguments = Handle<Object>(
+ Accessors::FunctionGetArguments(*function,
+ NULL)->ToObjectUnchecked());
+ ASSERT(*arguments != isolate->heap()->null_value());
+ ASSERT(*arguments != isolate->heap()->undefined_value());
+ }
+ frame->SetExpression(i, *arguments);
+ }
+ }
+
+ isolate->compilation_cache()->MarkForLazyOptimizing(function);
+ if (type == Deoptimizer::EAGER) {
+ RUNTIME_ASSERT(function->IsOptimized());
+ } else {
+ RUNTIME_ASSERT(!function->IsOptimized());
+ }
+
+ // Avoid doing too much work when running with --always-opt and keep
+ // the optimized code around.
+ if (FLAG_always_opt || type == Deoptimizer::LAZY) {
+ return isolate->heap()->undefined_value();
+ }
+
+ // Count the number of optimized activations of the function.
+ int activations = 0;
+ while (!it.done()) {
+ JavaScriptFrame* frame = it.frame();
+ if (frame->is_optimized() && frame->function() == *function) {
+ activations++;
+ }
+ it.Advance();
+ }
+
+ // TODO(kasperl): For now, we cannot support removing the optimized
+ // code when we have recursive invocations of the same function.
+ if (activations == 0) {
+ if (FLAG_trace_deopt) {
+ PrintF("[removing optimized code for: ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+ function->ReplaceCode(function->shared()->code());
+ }
+ return isolate->heap()->undefined_value();
+}
+
+
+static MaybeObject* Runtime_NotifyOSR(RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
+ delete deoptimizer;
+ return isolate->heap()->undefined_value();
+}
+
+
+static MaybeObject* Runtime_DeoptimizeFunction(RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ if (!function->IsOptimized()) return isolate->heap()->undefined_value();
+
+ Deoptimizer::DeoptimizeFunction(*function);
+
+ return isolate->heap()->undefined_value();
+}
+
+
+static MaybeObject* Runtime_CompileForOnStackReplacement(
+ RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
+
+ // We're not prepared to handle a function with arguments object.
+ ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
+
+ // We have hit a back edge in an unoptimized frame for a function that was
+ // selected for on-stack replacement. Find the unoptimized code object.
+ Handle<Code> unoptimized(function->shared()->code(), isolate);
+ // Keep track of whether we've succeeded in optimizing.
+ bool succeeded = unoptimized->optimizable();
+ if (succeeded) {
+ // If we are trying to do OSR when there are already optimized
+ // activations of the function, it means (a) the function is directly or
+ // indirectly recursive and (b) an optimized invocation has been
+ // deoptimized so that we are currently in an unoptimized activation.
+ // Check for optimized activations of this function.
+ JavaScriptFrameIterator it;
+ while (succeeded && !it.done()) {
+ JavaScriptFrame* frame = it.frame();
+ succeeded = !frame->is_optimized() || frame->function() != *function;
+ it.Advance();
+ }
+ }
+
+ int ast_id = AstNode::kNoNumber;
+ if (succeeded) {
+ // The top JS function is this one, the PC is somewhere in the
+ // unoptimized code.
+ JavaScriptFrameIterator it;
+ JavaScriptFrame* frame = it.frame();
+ ASSERT(frame->function() == *function);
+ ASSERT(frame->LookupCode(isolate) == *unoptimized);
+ ASSERT(unoptimized->contains(frame->pc()));
+
+ // Use linear search of the unoptimized code's stack check table to find
+ // the AST id matching the PC.
+ Address start = unoptimized->instruction_start();
+ unsigned target_pc_offset = frame->pc() - start;
+ Address table_cursor = start + unoptimized->stack_check_table_start();
+ uint32_t table_length = Memory::uint32_at(table_cursor);
+ table_cursor += kIntSize;
+ for (unsigned i = 0; i < table_length; ++i) {
+ // Table entries are (AST id, pc offset) pairs.
+ uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize);
+ if (pc_offset == target_pc_offset) {
+ ast_id = static_cast<int>(Memory::uint32_at(table_cursor));
+ break;
+ }
+ table_cursor += 2 * kIntSize;
+ }
+ ASSERT(ast_id != AstNode::kNoNumber);
+ if (FLAG_trace_osr) {
+ PrintF("[replacing on-stack at AST id %d in ", ast_id);
+ function->PrintName();
+ PrintF("]\n");
+ }
+
+ // Try to compile the optimized code. A true return value from
+ // CompileOptimized means that compilation succeeded, not necessarily
+ // that optimization succeeded.
+ if (CompileOptimized(function, ast_id) && function->IsOptimized()) {
+ DeoptimizationInputData* data = DeoptimizationInputData::cast(
+ function->code()->deoptimization_data());
+ if (FLAG_trace_osr) {
+ PrintF("[on-stack replacement offset %d in optimized code]\n",
+ data->OsrPcOffset()->value());
+ }
+ ASSERT(data->OsrAstId()->value() == ast_id);
+ ASSERT(data->OsrPcOffset()->value() >= 0);
+ } else {
+ succeeded = false;
+ }
+ }
+
+ // Revert to the original stack checks in the original unoptimized code.
+ if (FLAG_trace_osr) {
+ PrintF("[restoring original stack checks in ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+ StackCheckStub check_stub;
+ Handle<Code> check_code = check_stub.GetCode();
+ Handle<Code> replacement_code(
+ isolate->builtins()->builtin(Builtins::OnStackReplacement));
+ // Iterate the unoptimized code and revert all the patched stack checks.
+ for (RelocIterator it(*unoptimized, RelocInfo::kCodeTargetMask);
+ !it.done();
+ it.next()) {
+ RelocInfo* rinfo = it.rinfo();
+ if (rinfo->target_address() == replacement_code->entry()) {
+ Deoptimizer::RevertStackCheckCode(rinfo, *check_code);
+ }
+ }
+
+ // Allow OSR only at nesting level zero again.
+ unoptimized->set_allow_osr_at_loop_nesting_level(0);
+
+ // If the optimization attempt succeeded, return the AST id tagged as a
+ // smi. This tells the builtin that we need to translate the unoptimized
+ // frame to an optimized one.
+ if (succeeded) {
+ ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
+ return Smi::FromInt(ast_id);
+ } else {
+ return Smi::FromInt(-1);
+ }
+}
+
+
static MaybeObject* Runtime_GetFunctionDelegate(RUNTIME_CALLING_CONVENTION) {
RUNTIME_GET_ISOLATE;
HandleScope scope(isolate);
@@ -8312,7 +8579,7 @@ static MaybeObject* Runtime_GetArrayKeys(RUNTIME_CALLING_CONVENTION) {
int keys_length = keys->length();
for (int i = 0; i < keys_length; i++) {
Object* key = keys->get(i);
- uint32_t index;
+ uint32_t index = 0;
if (!key->ToArrayIndex(&index) || index >= length) {
// Zap invalid keys.
keys->set_undefined(i);
@@ -8446,6 +8713,7 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
MaybeObject* maybe_value = receiver->GetPropertyWithCallback(
receiver, structure, name, result->holder());
if (!maybe_value->ToObject(&value)) {
+ if (maybe_value->IsRetryAfterGC()) return maybe_value;
ASSERT(maybe_value->IsException());
maybe_value = heap->isolate()->pending_exception();
heap->isolate()->clear_pending_exception();
@@ -8766,6 +9034,9 @@ static MaybeObject* Runtime_GetFrameDetails(RUNTIME_CALLING_CONVENTION) {
}
if (it.done()) return heap->undefined_value();
+ bool is_optimized_frame =
+ it.frame()->LookupCode(isolate)->kind() == Code::OPTIMIZED_FUNCTION;
+
// Traverse the saved contexts chain to find the active context for the
// selected frame.
SaveContext* save = isolate->save_context();
@@ -8799,18 +9070,28 @@ static MaybeObject* Runtime_GetFrameDetails(RUNTIME_CALLING_CONVENTION) {
// confusing.
Handle<FixedArray> locals =
isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
+
+ // Fill in the names of the locals.
for (int i = 0; i < info.NumberOfLocals(); i++) {
- // Name of the local.
locals->set(i * 2, *info.LocalName(i));
+ }
- // Fetch the value of the local - either from the stack or from a
- // heap-allocated context.
- if (i < info.number_of_stack_slots()) {
+ // Fill in the values of the locals.
+ for (int i = 0; i < info.NumberOfLocals(); i++) {
+ if (is_optimized_frame) {
+ // If we are inspecting an optimized frame use undefined as the
+ // value for all locals.
+ //
+ // TODO(3141533): We should be able to get the correct values
+ // for locals in optimized frames.
+ locals->set(i * 2 + 1, isolate->heap()->undefined_value());
+ } else if (i < info.number_of_stack_slots()) {
+ // Get the value from the stack.
locals->set(i * 2 + 1, it.frame()->GetExpression(i));
} else {
- Handle<String> name = info.LocalName(i);
// Traverse the context chain to the function context as all local
// variables stored in the context will be on the function context.
+ Handle<String> name = info.LocalName(i);
while (!context->is_function_context()) {
context = Handle<Context>(context->previous());
}
@@ -8820,9 +9101,12 @@ static MaybeObject* Runtime_GetFrameDetails(RUNTIME_CALLING_CONVENTION) {
}
}
- // Check whether this frame is positioned at return.
- int at_return = (index == 0) ?
- isolate->debug()->IsBreakAtReturn(it.frame()) : false;
+ // Check whether this frame is positioned at return. If not top
+ // frame or if the frame is optimized it cannot be at a return.
+ bool at_return = false;
+ if (!is_optimized_frame && index == 0) {
+ at_return = isolate->debug()->IsBreakAtReturn(it.frame());
+ }
// If positioned just before return find the value to be returned and add it
// to the frame information.
@@ -8918,8 +9202,13 @@ static MaybeObject* Runtime_GetFrameDetails(RUNTIME_CALLING_CONVENTION) {
details->set(details_index++, heap->undefined_value());
}
- // Parameter value.
- if (i < it.frame()->GetProvidedParametersCount()) {
+ // Parameter value. If we are inspecting an optimized frame, use
+ // undefined as the value.
+ //
+ // TODO(3141533): We should be able to get the actual parameter
+ // value for optimized frames.
+ if (!is_optimized_frame &&
+ (i < it.frame()->GetProvidedParametersCount())) {
details->set(details_index++, it.frame()->GetParameter(i));
} else {
details->set(details_index++, heap->undefined_value());
@@ -9538,7 +9827,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate,
// Iterate the heap looking for SharedFunctionInfo generated from the
// script. The inner most SharedFunctionInfo containing the source position
// for the requested break point is found.
- // NOTE: This might reqire several heap iterations. If the SharedFunctionInfo
+ // NOTE: This might require several heap iterations. If the SharedFunctionInfo
// which is found is not compiled it is compiled and the heap is iterated
// again as the compilation might create inner functions from the newly
// compiled function and the actual requested break point might be in one of
@@ -10395,6 +10684,17 @@ static MaybeObject* Runtime_LiveEditReplaceScript(RUNTIME_CALLING_CONVENTION) {
}
}
+
+static MaybeObject* Runtime_LiveEditFunctionSourceUpdated(
+ RUNTIME_CALLING_CONVENTION) {
+ RUNTIME_GET_ISOLATE;
+ ASSERT(args.length() == 1);
+ HandleScope scope(isolate);
+ CONVERT_ARG_CHECKED(JSArray, shared_info, 0);
+ return LiveEdit::FunctionSourceUpdated(shared_info);
+}
+
+
// Replaces code of SharedFunctionInfo with a new one.
static MaybeObject* Runtime_LiveEditReplaceFunctionCode(
RUNTIME_CALLING_CONVENTION) {
@@ -10508,7 +10808,12 @@ static MaybeObject* Runtime_GetFunctionCodePositionFromSource(
CONVERT_ARG_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
- Handle<Code> code(function->code());
+ Handle<Code> code(function->code(), isolate);
+
+ if (code->kind() != Code::FUNCTION &&
+ code->kind() != Code::OPTIMIZED_FUNCTION) {
+ return isolate->heap()->undefined_value();
+ }
RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
int closest_pc = 0;
@@ -10668,9 +10973,9 @@ static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
}
-// Collect the raw data for a stack trace. Returns an array of three
-// element segments each containing a receiver, function and native
-// code offset.
+// Collect the raw data for a stack trace. Returns an array of 4
+// element segments each containing a receiver, function, code and
+// native code offset.
static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) {
RUNTIME_GET_ISOLATE;
ASSERT_EQ(args.length(), 2);
@@ -10681,7 +10986,7 @@ static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) {
limit = Max(limit, 0); // Ensure that limit is not negative.
int initial_size = Min(limit, 10);
- Handle<JSArray> result = isolate->factory()->NewJSArray(initial_size * 3);
+ Handle<JSArray> result = isolate->factory()->NewJSArray(initial_size * 4);
StackFrameIterator iter;
// If the caller parameter is a function we skip frames until we're
@@ -10694,23 +10999,25 @@ static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) {
if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) {
frames_seen++;
JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
- Object* recv = frame->receiver();
- Object* fun = frame->function();
- Address pc = frame->pc();
- Address start = frame->LookupCode(isolate)->address();
- Smi* offset = Smi::FromInt(static_cast<int>(pc - start));
- FixedArray* elements = FixedArray::cast(result->elements());
- if (cursor + 2 < elements->length()) {
- elements->set(cursor++, recv);
- elements->set(cursor++, fun);
- elements->set(cursor++, offset);
- } else {
- HandleScope scope(isolate);
- Handle<Object> recv_handle(recv, isolate);
- Handle<Object> fun_handle(fun, isolate);
- SetElement(result, cursor++, recv_handle);
- SetElement(result, cursor++, fun_handle);
- SetElement(result, cursor++, Handle<Smi>(offset));
+ List<FrameSummary> frames(3); // Max 2 levels of inlining.
+ frame->Summarize(&frames);
+ for (int i = frames.length() - 1; i >= 0; i--) {
+ Handle<Object> recv = frames[i].receiver();
+ Handle<JSFunction> fun = frames[i].function();
+ Handle<Code> code = frames[i].code();
+ Handle<Smi> offset(Smi::FromInt(frames[i].offset()));
+ FixedArray* elements = FixedArray::cast(result->elements());
+ if (cursor + 3 < elements->length()) {
+ elements->set(cursor++, *recv);
+ elements->set(cursor++, *fun);
+ elements->set(cursor++, *code);
+ elements->set(cursor++, *offset);
+ } else {
+ SetElement(result, cursor++, recv);
+ SetElement(result, cursor++, fun);
+ SetElement(result, cursor++, code);
+ SetElement(result, cursor++, offset);
+ }
}
}
iter.Advance();
« 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