Index: src/accessors.cc |
diff --git a/src/accessors.cc b/src/accessors.cc |
index c7d9cfe94ca52f932ab07f2bc6d7ec0b7d8196b6..2b205d5d74d55cc7b81a100d0c8a7d1d182676e1 100644 |
--- a/src/accessors.cc |
+++ b/src/accessors.cc |
@@ -675,46 +675,36 @@ static void ComputeSlotMappingForArguments(JavaScriptFrame* frame, |
int inlined_frame_index, |
Vector<SlotRef>* args_slots) { |
AssertNoAllocation no_gc; |
- |
int deopt_index = AstNode::kNoNumber; |
- |
DeoptimizationInputData* data = |
static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
- |
TranslationIterator it(data->TranslationByteArray(), |
data->TranslationIndex(deopt_index)->value()); |
- |
Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
ASSERT(opcode == Translation::BEGIN); |
int frame_count = it.Next(); |
- |
USE(frame_count); |
ASSERT(frame_count > inlined_frame_index); |
- |
int frames_to_skip = inlined_frame_index; |
while (true) { |
opcode = static_cast<Translation::Opcode>(it.Next()); |
- |
// Skip over operands to advance to the next opcode. |
it.Skip(Translation::NumberOfOperandsFor(opcode)); |
- |
if (opcode == Translation::FRAME) { |
if (frames_to_skip == 0) { |
- // We reached frame corresponding to inlined function in question. |
- // Process translation commands for arguments. |
- |
- // Skip translation command for receiver. |
+ // We reached the frame corresponding to the inlined function |
+ // in question. Process the translation commands for the |
+ // arguments. |
+ // |
+ // Skip the translation command for the receiver. |
it.Skip(Translation::NumberOfOperandsFor( |
static_cast<Translation::Opcode>(it.Next()))); |
- |
// Compute slots for arguments. |
for (int i = 0; i < args_slots->length(); ++i) { |
(*args_slots)[i] = ComputeSlotForNextArgument(&it, data, frame); |
} |
- |
return; |
} |
- |
frames_to_skip--; |
} |
} |
@@ -727,16 +717,11 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction( |
JavaScriptFrame* frame, |
Handle<JSFunction> inlined_function, |
int inlined_frame_index) { |
- |
int args_count = inlined_function->shared()->formal_parameter_count(); |
- |
ScopedVector<SlotRef> args_slots(args_count); |
- |
ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots); |
- |
Handle<JSObject> arguments = |
Factory::NewArgumentsObject(inlined_function, args_count); |
- |
Handle<FixedArray> array = Factory::NewFixedArray(args_count); |
for (int i = 0; i < args_count; ++i) { |
Handle<Object> value = args_slots[i].GetValue(); |
@@ -766,39 +751,43 @@ MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) { |
if (functions[i] != *function) continue; |
if (i > 0) { |
- // Function in question was inlined. |
+ // The function in question was inlined. Inlined functions have the |
+ // correct number of arguments and no allocated arguments object, so |
+ // we can construct a fresh one by interpreting the function's |
+ // deoptimization input data. |
return ConstructArgumentsObjectForInlinedFunction(frame, function, i); |
- } else { |
+ } |
+ |
+ if (!frame->is_optimized()) { |
// If there is an arguments variable in the stack, we return that. |
- int index = function->shared()->scope_info()-> |
- StackSlotIndex(Heap::arguments_symbol()); |
+ Handle<SerializedScopeInfo> info(function->shared()->scope_info()); |
+ int index = info->StackSlotIndex(Heap::arguments_symbol()); |
if (index >= 0) { |
- Handle<Object> arguments = |
- Handle<Object>(frame->GetExpression(index)); |
+ Handle<Object> arguments(frame->GetExpression(index)); |
if (!arguments->IsArgumentsMarker()) return *arguments; |
} |
- |
- // If there isn't an arguments variable in the stack, we need to |
- // find the frame that holds the actual arguments passed to the |
- // function on the stack. |
- it.AdvanceToArgumentsFrame(); |
- frame = it.frame(); |
- |
- // Get the number of arguments and construct an arguments object |
- // mirror for the right frame. |
- const int length = frame->GetProvidedParametersCount(); |
- Handle<JSObject> arguments = Factory::NewArgumentsObject(function, |
- length); |
- Handle<FixedArray> array = Factory::NewFixedArray(length); |
- |
- // Copy the parameters to the arguments object. |
- ASSERT(array->length() == length); |
- for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); |
- arguments->set_elements(*array); |
- |
- // Return the freshly allocated arguments object. |
- return *arguments; |
} |
+ |
+ // If there is no arguments variable in the stack or we have an |
+ // optimized frame, we find the frame that holds the actual arguments |
+ // passed to the function. |
+ it.AdvanceToArgumentsFrame(); |
+ frame = it.frame(); |
+ |
+ // Get the number of arguments and construct an arguments object |
+ // mirror for the right frame. |
+ const int length = frame->GetProvidedParametersCount(); |
+ Handle<JSObject> arguments = Factory::NewArgumentsObject(function, |
+ length); |
+ Handle<FixedArray> array = Factory::NewFixedArray(length); |
+ |
+ // Copy the parameters to the arguments object. |
+ ASSERT(array->length() == length); |
+ for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); |
+ arguments->set_elements(*array); |
+ |
+ // Return the freshly allocated arguments object. |
+ return *arguments; |
} |
functions.Rewind(0); |
} |