diff options
Diffstat (limited to 'deps/v8/src/compiler/code-generator.cc')
-rw-r--r-- | deps/v8/src/compiler/code-generator.cc | 199 |
1 files changed, 130 insertions, 69 deletions
diff --git a/deps/v8/src/compiler/code-generator.cc b/deps/v8/src/compiler/code-generator.cc index 97f780d1cb..313567ed87 100644 --- a/deps/v8/src/compiler/code-generator.cc +++ b/deps/v8/src/compiler/code-generator.cc @@ -34,14 +34,14 @@ class CodeGenerator::JumpTable final : public ZoneObject { CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, InstructionSequence* code, CompilationInfo* info) - : frame_(frame), + : frame_access_state_(new (code->zone()) FrameAccessState(frame)), linkage_(linkage), code_(code), info_(info), labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), current_block_(RpoNumber::Invalid()), current_source_position_(SourcePosition::Unknown()), - masm_(info->isolate(), NULL, 0), + masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kYes), resolver_(this), safepoints_(code->zone()), handlers_(code->zone()), @@ -52,11 +52,13 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, last_lazy_deopt_pc_(0), jump_tables_(nullptr), ools_(nullptr), - osr_pc_offset_(-1), - needs_frame_(frame->GetSpillSlotCount() > 0 || code->ContainsCall()) { + osr_pc_offset_(-1) { for (int i = 0; i < code->InstructionBlockCount(); ++i) { new (&labels_[i]) Label; } + if (code->ContainsCall()) { + frame->MarkNeedsFrame(); + } } @@ -90,6 +92,14 @@ Handle<Code> CodeGenerator::GenerateCode() { } inlined_function_count_ = deoptimization_literals_.size(); + // Define deoptimization literals for all unoptimized code objects of inlined + // functions. This ensures unoptimized code is kept alive by optimized code. + for (auto& inlined : info->inlined_functions()) { + if (!inlined.shared_info.is_identical_to(info->shared_info())) { + DefineDeoptimizationLiteral(inlined.inlined_code_object_root); + } + } + // Assemble all non-deferred blocks, followed by deferred ones. for (int deferred = 0; deferred < 2; ++deferred) { for (auto const block : code()->instruction_blocks()) { @@ -206,8 +216,10 @@ Handle<Code> CodeGenerator::GenerateCode() { bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { - return code()->InstructionBlockAt(current_block_)->ao_number().IsNext( - code()->InstructionBlockAt(block)->ao_number()); + return code() + ->InstructionBlockAt(current_block_) + ->ao_number() + .IsNext(code()->InstructionBlockAt(block)->ao_number()); } @@ -479,62 +491,84 @@ FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( } -namespace { - -struct OperandAndType { - InstructionOperand* const operand; - MachineType const type; -}; +void CodeGenerator::TranslateStateValueDescriptor( + StateValueDescriptor* desc, Translation* translation, + InstructionOperandIterator* iter) { + if (desc->IsNested()) { + translation->BeginCapturedObject(static_cast<int>(desc->size())); + for (size_t index = 0; index < desc->fields().size(); index++) { + TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); + } + } else if (desc->IsDuplicate()) { + translation->DuplicateObject(static_cast<int>(desc->id())); + } else { + DCHECK(desc->IsPlain()); + AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), + desc->type()); + } +} -OperandAndType TypedOperandForFrameState(FrameStateDescriptor* descriptor, - Instruction* instr, - size_t frame_state_offset, - size_t index, - OutputFrameStateCombine combine) { - DCHECK(index < descriptor->GetSize(combine)); - switch (combine.kind()) { - case OutputFrameStateCombine::kPushOutput: { - DCHECK(combine.GetPushCount() <= instr->OutputCount()); - size_t size_without_output = - descriptor->GetSize(OutputFrameStateCombine::Ignore()); - // If the index is past the existing stack items, return the output. - if (index >= size_without_output) { - return {instr->OutputAt(index - size_without_output), kMachAnyTagged}; +void CodeGenerator::TranslateFrameStateDescriptorOperands( + FrameStateDescriptor* desc, InstructionOperandIterator* iter, + OutputFrameStateCombine combine, Translation* translation) { + for (size_t index = 0; index < desc->GetSize(combine); index++) { + switch (combine.kind()) { + case OutputFrameStateCombine::kPushOutput: { + DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); + size_t size_without_output = + desc->GetSize(OutputFrameStateCombine::Ignore()); + // If the index is past the existing stack items in values_. + if (index >= size_without_output) { + // Materialize the result of the call instruction in this slot. + AddTranslationForOperand( + translation, iter->instruction(), + iter->instruction()->OutputAt(index - size_without_output), + MachineType::AnyTagged()); + continue; + } + break; } - break; + case OutputFrameStateCombine::kPokeAt: + // The result of the call should be placed at position + // [index_from_top] in the stack (overwriting whatever was + // previously there). + size_t index_from_top = + desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); + if (index >= index_from_top && + index < index_from_top + iter->instruction()->OutputCount()) { + AddTranslationForOperand( + translation, iter->instruction(), + iter->instruction()->OutputAt(index - index_from_top), + MachineType::AnyTagged()); + iter->Advance(); // We do not use this input, but we need to + // advace, as the input got replaced. + continue; + } + break; } - case OutputFrameStateCombine::kPokeAt: - size_t index_from_top = - descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); - if (index >= index_from_top && - index < index_from_top + instr->OutputCount()) { - return {instr->OutputAt(index - index_from_top), kMachAnyTagged}; - } - break; + StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); + TranslateStateValueDescriptor(&value_desc->fields()[index], translation, + iter); } - return {instr->InputAt(frame_state_offset + index), - descriptor->GetType(index)}; } -} // namespace - void CodeGenerator::BuildTranslationForFrameStateDescriptor( - FrameStateDescriptor* descriptor, Instruction* instr, - Translation* translation, size_t frame_state_offset, - OutputFrameStateCombine state_combine) { + FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, + Translation* translation, OutputFrameStateCombine state_combine) { // Outer-most state must be added to translation first. if (descriptor->outer_state() != nullptr) { - BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, - translation, frame_state_offset, + BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, + translation, OutputFrameStateCombine::Ignore()); } - frame_state_offset += descriptor->outer_state()->GetTotalSize(); Handle<SharedFunctionInfo> shared_info; if (!descriptor->shared_info().ToHandle(&shared_info)) { - if (!info()->has_shared_info()) return; // Stub with no SharedFunctionInfo. + if (!info()->has_shared_info()) { + return; // Stub with no SharedFunctionInfo. + } shared_info = info()->shared_info(); } int shared_info_id = DefineDeoptimizationLiteral(shared_info); @@ -546,18 +580,25 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor( static_cast<unsigned int>(descriptor->GetSize(state_combine) - (1 + descriptor->parameters_count()))); break; + case FrameStateType::kInterpretedFunction: + translation->BeginInterpretedFrame( + descriptor->bailout_id(), shared_info_id, + static_cast<unsigned int>(descriptor->locals_count())); + break; case FrameStateType::kArgumentsAdaptor: translation->BeginArgumentsAdaptorFrame( shared_info_id, static_cast<unsigned int>(descriptor->parameters_count())); break; + case FrameStateType::kConstructStub: + translation->BeginConstructStubFrame( + shared_info_id, + static_cast<unsigned int>(descriptor->parameters_count())); + break; } - for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) { - OperandAndType op = TypedOperandForFrameState( - descriptor, instr, frame_state_offset, i, state_combine); - AddTranslationForOperand(translation, instr, op.operand, op.type); - } + TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine, + translation); } @@ -571,8 +612,9 @@ int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, Translation translation( &translations_, static_cast<int>(descriptor->GetFrameCount()), static_cast<int>(descriptor->GetJSFrameCount()), zone()); - BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, - frame_state_offset, state_combine); + InstructionOperandIterator iter(instr, frame_state_offset); + BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, + state_combine); int deoptimization_id = static_cast<int>(deoptimization_states_.size()); @@ -588,37 +630,39 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, InstructionOperand* op, MachineType type) { if (op->IsStackSlot()) { - if (type == kMachBool || type == kRepBit) { + if (type.representation() == MachineRepresentation::kBit) { translation->StoreBoolStackSlot(LocationOperand::cast(op)->index()); - } else if (type == kMachInt32 || type == kMachInt8 || type == kMachInt16) { + } else if (type == MachineType::Int8() || type == MachineType::Int16() || + type == MachineType::Int32()) { translation->StoreInt32StackSlot(LocationOperand::cast(op)->index()); - } else if (type == kMachUint32 || type == kMachUint16 || - type == kMachUint8) { + } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || + type == MachineType::Uint32()) { translation->StoreUint32StackSlot(LocationOperand::cast(op)->index()); - } else if ((type & kRepMask) == kRepTagged) { + } else if (type.representation() == MachineRepresentation::kTagged) { translation->StoreStackSlot(LocationOperand::cast(op)->index()); } else { CHECK(false); } } else if (op->IsDoubleStackSlot()) { - DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0); + DCHECK(IsFloatingPoint(type.representation())); translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index()); } else if (op->IsRegister()) { InstructionOperandConverter converter(this, instr); - if (type == kMachBool || type == kRepBit) { + if (type.representation() == MachineRepresentation::kBit) { translation->StoreBoolRegister(converter.ToRegister(op)); - } else if (type == kMachInt32 || type == kMachInt8 || type == kMachInt16) { + } else if (type == MachineType::Int8() || type == MachineType::Int16() || + type == MachineType::Int32()) { translation->StoreInt32Register(converter.ToRegister(op)); - } else if (type == kMachUint32 || type == kMachUint16 || - type == kMachUint8) { + } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || + type == MachineType::Uint32()) { translation->StoreUint32Register(converter.ToRegister(op)); - } else if ((type & kRepMask) == kRepTagged) { + } else if (type.representation() == MachineRepresentation::kTagged) { translation->StoreRegister(converter.ToRegister(op)); } else { CHECK(false); } } else if (op->IsDoubleRegister()) { - DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0); + DCHECK(IsFloatingPoint(type.representation())); InstructionOperandConverter converter(this, instr); translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); } else if (op->IsImmediate()) { @@ -627,20 +671,23 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, Handle<Object> constant_object; switch (constant.type()) { case Constant::kInt32: - DCHECK(type == kMachInt32 || type == kMachUint32 || type == kRepBit); + DCHECK(type == MachineType::Int32() || type == MachineType::Uint32() || + type.representation() == MachineRepresentation::kBit); constant_object = isolate()->factory()->NewNumberFromInt(constant.ToInt32()); break; case Constant::kFloat32: - DCHECK((type & (kRepFloat32 | kRepTagged)) != 0); + DCHECK(type.representation() == MachineRepresentation::kFloat32 || + type.representation() == MachineRepresentation::kTagged); constant_object = isolate()->factory()->NewNumber(constant.ToFloat32()); break; case Constant::kFloat64: - DCHECK((type & (kRepFloat64 | kRepTagged)) != 0); + DCHECK(type.representation() == MachineRepresentation::kFloat64 || + type.representation() == MachineRepresentation::kTagged); constant_object = isolate()->factory()->NewNumber(constant.ToFloat64()); break; case Constant::kHeapObject: - DCHECK((type & kRepMask) == kRepTagged); + DCHECK(type.representation() == MachineRepresentation::kTagged); constant_object = constant.ToHeapObject(); break; default: @@ -663,6 +710,20 @@ void CodeGenerator::MarkLazyDeoptSite() { } +int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { + CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); + int spill_slots = frame()->GetSpillSlotCount(); + bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; + // Leave the PC on the stack on platforms that have that as part of their ABI + int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; + int sp_slot_delta = + has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0; + // Discard only slots that won't be used by new parameters. + sp_slot_delta += stack_param_delta; + return sp_slot_delta; +} + + OutOfLineCode::OutOfLineCode(CodeGenerator* gen) : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { gen->ools_ = this; |