summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/code-generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/code-generator.cc')
-rw-r--r--deps/v8/src/compiler/code-generator.cc168
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);
}
}