| Index: src/deoptimizer.cc
|
| diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
|
| index d70cc28ae0a9c9b330e05c44ce6ad89d8be88ec2..63b82b79e9ed0f217535a5d05f7b91494389bd1a 100644
|
| --- a/src/deoptimizer.cc
|
| +++ b/src/deoptimizer.cc
|
| @@ -1194,4 +1194,103 @@ DeoptimizingCodeListNode::~DeoptimizingCodeListNode() {
|
| }
|
|
|
|
|
| +// We can't intermix stack decoding and allocations because
|
| +// deoptimization infrastracture is not GC safe.
|
| +// Thus we build a temporary structure in malloced space.
|
| +SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
|
| + DeoptimizationInputData* data,
|
| + JavaScriptFrame* frame) {
|
| + Translation::Opcode opcode =
|
| + static_cast<Translation::Opcode>(iterator->Next());
|
| +
|
| + switch (opcode) {
|
| + case Translation::BEGIN:
|
| + case Translation::FRAME:
|
| + // Peeled off before getting here.
|
| + break;
|
| +
|
| + case Translation::ARGUMENTS_OBJECT:
|
| + // This can be only emitted for local slots not for argument slots.
|
| + break;
|
| +
|
| + case Translation::REGISTER:
|
| + case Translation::INT32_REGISTER:
|
| + case Translation::DOUBLE_REGISTER:
|
| + case Translation::DUPLICATE:
|
| + // We are at safepoint which corresponds to call. All registers are
|
| + // saved by caller so there would be no live registers at this
|
| + // point. Thus these translation commands should not be used.
|
| + break;
|
| +
|
| + case Translation::STACK_SLOT: {
|
| + int slot_index = iterator->Next();
|
| + Address slot_addr = SlotAddress(frame, slot_index);
|
| + return SlotRef(slot_addr, SlotRef::TAGGED);
|
| + }
|
| +
|
| + case Translation::INT32_STACK_SLOT: {
|
| + int slot_index = iterator->Next();
|
| + Address slot_addr = SlotAddress(frame, slot_index);
|
| + return SlotRef(slot_addr, SlotRef::INT32);
|
| + }
|
| +
|
| + case Translation::DOUBLE_STACK_SLOT: {
|
| + int slot_index = iterator->Next();
|
| + Address slot_addr = SlotAddress(frame, slot_index);
|
| + return SlotRef(slot_addr, SlotRef::DOUBLE);
|
| + }
|
| +
|
| + case Translation::LITERAL: {
|
| + int literal_index = iterator->Next();
|
| + return SlotRef(data->LiteralArray()->get(literal_index));
|
| + }
|
| + }
|
| +
|
| + UNREACHABLE();
|
| + return SlotRef();
|
| +}
|
| +
|
| +
|
| +void SlotRef::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 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--;
|
| + }
|
| + }
|
| +
|
| + UNREACHABLE();
|
| +}
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|