Index: src/accessors.cc |
diff --git a/src/accessors.cc b/src/accessors.cc |
index e33b4d794077954ac9ef701d9e42b64d5c5474d8..ee7636ec4b3ebbd7ef60b389026b488f2e1542f7 100644 |
--- a/src/accessors.cc |
+++ b/src/accessors.cc |
@@ -568,172 +568,6 @@ const AccessorDescriptor Accessors::FunctionName = { |
// Accessors::FunctionArguments |
// |
-static Address SlotAddress(JavaScriptFrame* frame, int slot_index) { |
- if (slot_index >= 0) { |
- const int offset = JavaScriptFrameConstants::kLocal0Offset; |
- return frame->fp() + offset - (slot_index * kPointerSize); |
- } else { |
- const int offset = JavaScriptFrameConstants::kReceiverOffset; |
- return frame->caller_sp() + offset + (slot_index * kPointerSize); |
- } |
-} |
- |
- |
-// We can't intermix stack decoding and allocations because |
-// deoptimization infrastracture is not GC safe. |
-// Thus we build a temporary structure in malloced space. |
-class SlotRef BASE_EMBEDDED { |
- public: |
- enum SlotRepresentation { |
- UNKNOWN, |
- TAGGED, |
- INT32, |
- DOUBLE, |
- LITERAL |
- }; |
- |
- SlotRef() |
- : addr_(NULL), representation_(UNKNOWN) { } |
- |
- SlotRef(Address addr, SlotRepresentation representation) |
- : addr_(addr), representation_(representation) { } |
- |
- explicit SlotRef(Object* literal) |
- : literal_(literal), representation_(LITERAL) { } |
- |
- Handle<Object> GetValue() { |
- switch (representation_) { |
- case TAGGED: |
- return Handle<Object>(Memory::Object_at(addr_)); |
- |
- case INT32: { |
- int value = Memory::int32_at(addr_); |
- if (Smi::IsValid(value)) { |
- return Handle<Object>(Smi::FromInt(value)); |
- } else { |
- return Isolate::Current()->factory()->NewNumberFromInt(value); |
- } |
- } |
- |
- case DOUBLE: { |
- double value = Memory::double_at(addr_); |
- return Isolate::Current()->factory()->NewNumber(value); |
- } |
- |
- case LITERAL: |
- return literal_; |
- |
- default: |
- UNREACHABLE(); |
- return Handle<Object>::null(); |
- } |
- } |
- |
- private: |
- Address addr_; |
- Handle<Object> literal_; |
- SlotRepresentation representation_; |
-}; |
- |
- |
-static 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(); |
-} |
- |
- |
- |
- |
- |
-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 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(); |
-} |
- |
static MaybeObject* ConstructArgumentsObjectForInlinedFunction( |
JavaScriptFrame* frame, |
@@ -742,7 +576,9 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction( |
Factory* factory = Isolate::Current()->factory(); |
int args_count = inlined_function->shared()->formal_parameter_count(); |
ScopedVector<SlotRef> args_slots(args_count); |
- ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots); |
+ SlotRef::ComputeSlotMappingForArguments(frame, |
+ inlined_frame_index, |
+ &args_slots); |
Handle<JSObject> arguments = |
factory->NewArgumentsObject(inlined_function, args_count); |
Handle<FixedArray> array = factory->NewFixedArray(args_count); |