diff options
Diffstat (limited to 'deps/v8/src/compiler/code-generator.cc')
-rw-r--r-- | deps/v8/src/compiler/code-generator.cc | 168 |
1 files changed, 120 insertions, 48 deletions
diff --git a/deps/v8/src/compiler/code-generator.cc b/deps/v8/src/compiler/code-generator.cc index f22c479780..6b04eef624 100644 --- a/deps/v8/src/compiler/code-generator.cc +++ b/deps/v8/src/compiler/code-generator.cc @@ -12,9 +12,14 @@ namespace v8 { namespace internal { namespace compiler { -CodeGenerator::CodeGenerator(InstructionSequence* code) - : code_(code), - current_block_(NULL), +CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, + InstructionSequence* code, CompilationInfo* info) + : frame_(frame), + linkage_(linkage), + code_(code), + info_(info), + labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), + current_block_(BasicBlock::RpoNumber::Invalid()), current_source_position_(SourcePosition::Invalid()), masm_(code->zone()->isolate(), NULL, 0), resolver_(this), @@ -22,11 +27,15 @@ CodeGenerator::CodeGenerator(InstructionSequence* code) deoptimization_states_(code->zone()), deoptimization_literals_(code->zone()), translations_(code->zone()), - last_lazy_deopt_pc_(0) {} + last_lazy_deopt_pc_(0) { + for (int i = 0; i < code->InstructionBlockCount(); ++i) { + new (&labels_[i]) Label; + } +} Handle<Code> CodeGenerator::GenerateCode() { - CompilationInfo* info = linkage()->info(); + CompilationInfo* info = this->info(); // Emit a code line info recording start event. PositionsRecorder* recorder = masm()->positions_recorder(); @@ -41,10 +50,25 @@ Handle<Code> CodeGenerator::GenerateCode() { info->set_prologue_offset(masm()->pc_offset()); AssemblePrologue(); - // Assemble all instructions. - for (InstructionSequence::const_iterator i = code()->begin(); - i != code()->end(); ++i) { - AssembleInstruction(*i); + // Assemble all non-deferred blocks, followed by deferred ones. + for (int deferred = 0; deferred < 2; ++deferred) { + for (auto const block : code()->instruction_blocks()) { + if (block->IsDeferred() == (deferred == 0)) { + continue; + } + // Bind a label for a block. + current_block_ = block->rpo_number(); + if (FLAG_code_comments) { + // TODO(titzer): these code comments are a giant memory leak. + Vector<char> buffer = Vector<char>::New(32); + SNPrintF(buffer, "-- B%d start --", block->id().ToInt()); + masm()->RecordComment(buffer.start()); + } + masm()->bind(GetLabel(current_block_)); + for (int i = block->code_start(); i < block->code_end(); ++i) { + AssembleInstruction(code()->InstructionAt(i)); + } + } } FinishCode(masm()); @@ -80,6 +104,12 @@ Handle<Code> CodeGenerator::GenerateCode() { } +bool CodeGenerator::IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const { + return code()->InstructionBlockAt(current_block_)->ao_number().IsNext( + code()->InstructionBlockAt(block)->ao_number()); +} + + void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind, int arguments, Safepoint::DeoptMode deopt_mode) { @@ -100,18 +130,6 @@ void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind, void CodeGenerator::AssembleInstruction(Instruction* instr) { - if (instr->IsBlockStart()) { - // Bind a label for a block start and handle parallel moves. - BlockStartInstruction* block_start = BlockStartInstruction::cast(instr); - current_block_ = block_start->block(); - if (FLAG_code_comments) { - // TODO(titzer): these code comments are a giant memory leak. - Vector<char> buffer = Vector<char>::New(32); - SNPrintF(buffer, "-- B%d start --", block_start->block()->id()); - masm()->RecordComment(buffer.start()); - } - masm()->bind(block_start->label()); - } if (instr->IsGapMoves()) { // Handle parallel moves associated with the gap instruction. AssembleGap(GapInstruction::cast(instr)); @@ -147,7 +165,7 @@ void CodeGenerator::AssembleSourcePosition(SourcePositionInstruction* instr) { masm()->positions_recorder()->WriteRecordedPositions(); if (FLAG_code_comments) { Vector<char> buffer = Vector<char>::New(256); - CompilationInfo* info = linkage()->info(); + CompilationInfo* info = this->info(); int ln = Script::GetLineNumber(info->script(), code_pos); int cn = Script::GetColumnNumber(info->script(), code_pos); if (info->script()->name()->IsString()) { @@ -177,7 +195,7 @@ void CodeGenerator::AssembleGap(GapInstruction* instr) { void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) { - CompilationInfo* info = linkage()->info(); + CompilationInfo* info = this->info(); int deopt_count = static_cast<int>(deoptimization_states_.size()); if (deopt_count == 0) return; Handle<DeoptimizationInputData> data = @@ -260,17 +278,17 @@ void CodeGenerator::AddSafepointAndDeopt(Instruction* instr) { // because it is only used to get locals and arguments (by the debugger and // f.arguments), and those are the same in the pre-call and post-call // states. - if (descriptor->state_combine() != kIgnoreOutput) { - deopt_state_id = - BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput); + if (!descriptor->state_combine().IsOutputIgnored()) { + deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, + OutputFrameStateCombine::Ignore()); } #if DEBUG // Make sure all the values live in stack slots or they are immediates. // (The values should not live in register because registers are clobbered // by calls.) - for (size_t i = 0; i < descriptor->size(); i++) { + for (size_t i = 0; i < descriptor->GetSize(); i++) { InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); - CHECK(op->IsStackSlot() || op->IsImmediate()); + CHECK(op->IsStackSlot() || op->IsDoubleStackSlot() || op->IsImmediate()); } #endif safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); @@ -296,6 +314,44 @@ FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( return code()->GetFrameStateDescriptor(state_id); } +struct OperandAndType { + OperandAndType(InstructionOperand* operand, MachineType type) + : operand_(operand), type_(type) {} + + InstructionOperand* operand_; + MachineType type_; +}; + +static 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 OperandAndType(instr->OutputAt(index - size_without_output), + kMachAnyTagged); + } + 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 OperandAndType(instr->OutputAt(index - index_from_top), + kMachAnyTagged); + } + break; + } + return OperandAndType(instr->InputAt(frame_state_offset + index), + descriptor->GetType(index)); +} + void CodeGenerator::BuildTranslationForFrameStateDescriptor( FrameStateDescriptor* descriptor, Instruction* instr, @@ -305,7 +361,7 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor( if (descriptor->outer_state() != NULL) { BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, translation, frame_state_offset, - kIgnoreOutput); + OutputFrameStateCombine::Ignore()); } int id = Translation::kSelfLiteralId; @@ -318,7 +374,8 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor( case JS_FRAME: translation->BeginJSFrame( descriptor->bailout_id(), id, - static_cast<unsigned int>(descriptor->GetHeight(state_combine))); + static_cast<unsigned int>(descriptor->GetSize(state_combine) - + descriptor->parameters_count())); break; case ARGUMENTS_ADAPTOR: translation->BeginArgumentsAdaptorFrame( @@ -327,19 +384,10 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor( } frame_state_offset += descriptor->outer_state()->GetTotalSize(); - for (size_t i = 0; i < descriptor->size(); i++) { - AddTranslationForOperand( - translation, instr, - instr->InputAt(static_cast<int>(frame_state_offset + i))); - } - - switch (state_combine) { - case kPushOutput: - DCHECK(instr->OutputCount() == 1); - AddTranslationForOperand(translation, instr, instr->OutputAt(0)); - break; - case kIgnoreOutput: - 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_); } } @@ -368,15 +416,36 @@ int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, void CodeGenerator::AddTranslationForOperand(Translation* translation, Instruction* instr, - InstructionOperand* op) { + InstructionOperand* op, + MachineType type) { if (op->IsStackSlot()) { - translation->StoreStackSlot(op->index()); + if (type == kMachBool || type == kMachInt32 || type == kMachInt8 || + type == kMachInt16) { + translation->StoreInt32StackSlot(op->index()); + } else if (type == kMachUint32) { + translation->StoreUint32StackSlot(op->index()); + } else if ((type & kRepMask) == kRepTagged) { + translation->StoreStackSlot(op->index()); + } else { + CHECK(false); + } } else if (op->IsDoubleStackSlot()) { + DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0); translation->StoreDoubleStackSlot(op->index()); } else if (op->IsRegister()) { InstructionOperandConverter converter(this, instr); - translation->StoreRegister(converter.ToRegister(op)); + if (type == kMachBool || type == kMachInt32 || type == kMachInt8 || + type == kMachInt16) { + translation->StoreInt32Register(converter.ToRegister(op)); + } else if (type == kMachUint32) { + translation->StoreUint32Register(converter.ToRegister(op)); + } else if ((type & kRepMask) == kRepTagged) { + translation->StoreRegister(converter.ToRegister(op)); + } else { + CHECK(false); + } } else if (op->IsDoubleRegister()) { + DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0); InstructionOperandConverter converter(this, instr); translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); } else if (op->IsImmediate()) { @@ -385,22 +454,25 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, Handle<Object> constant_object; switch (constant.type()) { case Constant::kInt32: + DCHECK(type == kMachInt32 || type == kMachUint32); constant_object = isolate()->factory()->NewNumberFromInt(constant.ToInt32()); break; case Constant::kFloat64: + DCHECK(type == kMachFloat64 || type == kMachAnyTagged); constant_object = isolate()->factory()->NewNumber(constant.ToFloat64()); break; case Constant::kHeapObject: + DCHECK((type & kRepMask) == kRepTagged); constant_object = constant.ToHeapObject(); break; default: - UNREACHABLE(); + CHECK(false); } int literal_id = DefineDeoptimizationLiteral(constant_object); translation->StoreLiteral(literal_id); } else { - UNREACHABLE(); + CHECK(false); } } |