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.cc199
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;