void CodeGenerator::AssembleInstruction(Instruction* instr) {
AssembleGaps(instr);
- if (instr->IsSourcePosition()) {
- AssembleSourcePosition(SourcePositionInstruction::cast(instr));
- } else {
- // Assemble architecture-specific code for the instruction.
- AssembleArchInstruction(instr);
-
- FlagsMode mode = FlagsModeField::decode(instr->opcode());
- FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
- if (mode == kFlags_branch) {
- // Assemble a branch after this instruction.
- InstructionOperandConverter i(this, instr);
- RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
- RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
-
- if (true_rpo == false_rpo) {
- // redundant branch.
- if (!IsNextInAssemblyOrder(true_rpo)) {
- AssembleArchJump(true_rpo);
- }
- return;
- }
- if (IsNextInAssemblyOrder(true_rpo)) {
- // true block is next, can fall through if condition negated.
- std::swap(true_rpo, false_rpo);
- condition = NegateFlagsCondition(condition);
+ AssembleSourcePosition(instr);
+ // Assemble architecture-specific code for the instruction.
+ AssembleArchInstruction(instr);
+
+ FlagsMode mode = FlagsModeField::decode(instr->opcode());
+ FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
+ if (mode == kFlags_branch) {
+ // Assemble a branch after this instruction.
+ InstructionOperandConverter i(this, instr);
+ RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
+ RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
+
+ if (true_rpo == false_rpo) {
+ // redundant branch.
+ if (!IsNextInAssemblyOrder(true_rpo)) {
+ AssembleArchJump(true_rpo);
}
- BranchInfo branch;
- branch.condition = condition;
- branch.true_label = GetLabel(true_rpo);
- branch.false_label = GetLabel(false_rpo);
- branch.fallthru = IsNextInAssemblyOrder(false_rpo);
- // Assemble architecture-specific branch.
- AssembleArchBranch(instr, &branch);
- } else if (mode == kFlags_set) {
- // Assemble a boolean materialization after this instruction.
- AssembleArchBoolean(instr, condition);
+ return;
+ }
+ if (IsNextInAssemblyOrder(true_rpo)) {
+ // true block is next, can fall through if condition negated.
+ std::swap(true_rpo, false_rpo);
+ condition = NegateFlagsCondition(condition);
}
+ BranchInfo branch;
+ branch.condition = condition;
+ branch.true_label = GetLabel(true_rpo);
+ branch.false_label = GetLabel(false_rpo);
+ branch.fallthru = IsNextInAssemblyOrder(false_rpo);
+ // Assemble architecture-specific branch.
+ AssembleArchBranch(instr, &branch);
+ } else if (mode == kFlags_set) {
+ // Assemble a boolean materialization after this instruction.
+ AssembleArchBoolean(instr, condition);
}
}
-void CodeGenerator::AssembleSourcePosition(SourcePositionInstruction* instr) {
- SourcePosition source_position = instr->source_position();
+void CodeGenerator::AssembleSourcePosition(Instruction* instr) {
+ SourcePosition source_position;
+ if (!code()->GetSourcePosition(instr, &source_position)) return;
if (source_position == current_source_position_) return;
DCHECK(!source_position.IsInvalid());
- if (!source_position.IsUnknown()) {
- int code_pos = source_position.raw();
- masm()->positions_recorder()->RecordPosition(source_position.raw());
- masm()->positions_recorder()->WriteRecordedPositions();
- if (FLAG_code_comments) {
- Vector<char> buffer = Vector<char>::New(256);
- 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()) {
- Handle<String> file(String::cast(info->script()->name()));
- base::OS::SNPrintF(buffer.start(), buffer.length(), "-- %s:%d:%d --",
- file->ToCString().get(), ln, cn);
- } else {
- base::OS::SNPrintF(buffer.start(), buffer.length(),
- "-- <unknown>:%d:%d --", ln, cn);
- }
- masm()->RecordComment(buffer.start());
+ current_source_position_ = source_position;
+ if (source_position.IsUnknown()) return;
+ int code_pos = source_position.raw();
+ masm()->positions_recorder()->RecordPosition(source_position.raw());
+ masm()->positions_recorder()->WriteRecordedPositions();
+ if (FLAG_code_comments) {
+ Vector<char> buffer = Vector<char>::New(256);
+ 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()) {
+ Handle<String> file(String::cast(info->script()->name()));
+ base::OS::SNPrintF(buffer.start(), buffer.length(), "-- %s:%d:%d --",
+ file->ToCString().get(), ln, cn);
+ } else {
+ base::OS::SNPrintF(buffer.start(), buffer.length(),
+ "-- <unknown>:%d:%d --", ln, cn);
}
+ masm()->RecordComment(buffer.start());
}
- current_source_position_ = source_position;
}
// Assemble code for the specified instruction.
void AssembleInstruction(Instruction* instr);
- void AssembleSourcePosition(SourcePositionInstruction* instr);
+ void AssembleSourcePosition(Instruction* instr);
void AssembleGaps(Instruction* instr);
// ===========================================================================
size_t current_node_end = instructions_.size();
VisitNode(node);
std::reverse(instructions_.begin() + current_node_end, instructions_.end());
+ if (instructions_.size() == current_node_end) continue;
+ // Mark source position on first instruction emitted.
+ SourcePosition source_position = source_positions_->GetSourcePosition(node);
+ if (source_position.IsUnknown()) continue;
+ DCHECK(!source_position.IsInvalid());
+ if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) {
+ sequence()->SetSourcePosition(instructions_[current_node_end],
+ source_position);
+ }
}
// We're done with the block.
void InstructionSelector::VisitNode(Node* node) {
DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
- SourcePosition source_position = source_positions_->GetSourcePosition(node);
- if (!source_position.IsUnknown()) {
- DCHECK(!source_position.IsInvalid());
- if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) {
- Emit(SourcePositionInstruction::New(instruction_zone(), source_position));
- }
- }
switch (node->opcode()) {
case IrOpcode::kStart:
case IrOpcode::kLoop:
if (instr.OutputCount() > 1) os << ") = ";
if (instr.OutputCount() == 1) os << " = ";
- if (instr.IsSourcePosition()) {
- const SourcePositionInstruction* pos =
- SourcePositionInstruction::cast(&instr);
- os << "position (" << pos->source_position().raw() << ")";
- } else {
- os << ArchOpcodeField::decode(instr.opcode());
- AddressingMode am = AddressingModeField::decode(instr.opcode());
- if (am != kMode_None) {
- os << " : " << AddressingModeField::decode(instr.opcode());
- }
- FlagsMode fm = FlagsModeField::decode(instr.opcode());
- if (fm != kFlags_none) {
- os << " && " << fm << " if "
- << FlagsConditionField::decode(instr.opcode());
- }
+ os << ArchOpcodeField::decode(instr.opcode());
+ AddressingMode am = AddressingModeField::decode(instr.opcode());
+ if (am != kMode_None) {
+ os << " : " << AddressingModeField::decode(instr.opcode());
+ }
+ FlagsMode fm = FlagsModeField::decode(instr.opcode());
+ if (fm != kFlags_none) {
+ os << " && " << fm << " if " << FlagsConditionField::decode(instr.opcode());
}
if (instr.InputCount() > 0) {
for (size_t i = 0; i < instr.InputCount(); i++) {
: isolate_(isolate),
zone_(instruction_zone),
instruction_blocks_(instruction_blocks),
+ source_positions_(zone()),
block_starts_(zone()),
constants_(ConstantMap::key_compare(),
ConstantMap::allocator_type(zone())),
}
+bool InstructionSequence::GetSourcePosition(const Instruction* instr,
+ SourcePosition* result) const {
+ auto it = source_positions_.find(instr);
+ if (it == source_positions_.end()) return false;
+ *result = it->second;
+ return true;
+}
+
+
+void InstructionSequence::SetSourcePosition(const Instruction* instr,
+ SourcePosition value) {
+ DCHECK(!value.IsInvalid());
+ DCHECK(!value.IsUnknown());
+ source_positions_.insert(std::make_pair(instr, value));
+}
+
+
FrameStateDescriptor::FrameStateDescriptor(
Zone* zone, const FrameStateCallInfo& state_info, size_t parameters_count,
size_t locals_count, size_t stack_count, FrameStateDescriptor* outer_state)
class Schedule;
-// A couple of reserved opcodes are used for internal use.
-const InstructionCode kSourcePositionInstruction = -1;
-
class InstructionOperand {
public:
static const int kInvalidVirtualRegister = -1;
bool NeedsReferenceMap() const { return IsCall(); }
bool HasReferenceMap() const { return reference_map_ != NULL; }
- bool IsSourcePosition() const {
- return opcode() == kSourcePositionInstruction;
- }
-
bool ClobbersRegisters() const { return IsCall(); }
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersDoubleRegisters() const { return IsCall(); }
std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr);
-class SourcePositionInstruction FINAL : public Instruction {
- public:
- static SourcePositionInstruction* New(Zone* zone, SourcePosition position) {
- void* buffer = zone->New(sizeof(SourcePositionInstruction));
- return new (buffer) SourcePositionInstruction(position);
- }
-
- SourcePosition source_position() const { return source_position_; }
-
- static SourcePositionInstruction* cast(Instruction* instr) {
- DCHECK(instr->IsSourcePosition());
- return static_cast<SourcePositionInstruction*>(instr);
- }
-
- static const SourcePositionInstruction* cast(const Instruction* instr) {
- DCHECK(instr->IsSourcePosition());
- return static_cast<const SourcePositionInstruction*>(instr);
- }
-
- private:
- explicit SourcePositionInstruction(SourcePosition source_position)
- : Instruction(kSourcePositionInstruction),
- source_position_(source_position) {
- DCHECK(!source_position_.IsInvalid());
- DCHECK(!source_position_.IsUnknown());
- }
-
- SourcePosition source_position_;
-};
-
-
class RpoNumber FINAL {
public:
static const int kInvalidRpoNumber = -1;
RpoNumber InputRpo(Instruction* instr, size_t index);
+ bool GetSourcePosition(const Instruction* instr,
+ SourcePosition* result) const;
+ void SetSourcePosition(const Instruction* instr, SourcePosition value);
+
private:
friend std::ostream& operator<<(std::ostream& os,
const PrintableInstructionSequence& code);
typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
+ typedef ZoneMap<const Instruction*, SourcePosition> SourcePositionMap;
Isolate* isolate_;
Zone* const zone_;
InstructionBlocks* const instruction_blocks_;
+ SourcePositionMap source_positions_;
IntVector block_starts_;
ConstantMap constants_;
Immediates immediates_;
// can't skip instructions with non redundant moves.
TRACE(" parallel move\n");
fallthru = false;
- } else if (instr->IsSourcePosition()) {
- // skip source positions.
- TRACE(" src pos\n");
- continue;
} else if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
// can't skip instructions with flags continuations.
TRACE(" flags\n");
typedef ZoneSet<InstructionOperand> OperandSet;
-bool GapsCanMoveOver(Instruction* instr) {
- return instr->IsSourcePosition() || instr->IsNop();
-}
+bool GapsCanMoveOver(Instruction* instr) { return instr->IsNop(); }
int FindFirstNonEmptySlot(Instruction* instr) {
for (auto pred_index : block->predecessors()) {
auto pred = code()->InstructionBlockAt(pred_index);
auto last_instr = code()->instructions()[pred->last_instruction_index()];
- if (last_instr->IsSourcePosition()) continue;
if (last_instr->IsCall()) return;
if (last_instr->TempCount() != 0) return;
if (last_instr->OutputCount() != 0) return;