Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc
index 712cfe0..086da56 100644
--- a/src/compiler/code-generator.cc
+++ b/src/compiler/code-generator.cc
@@ -31,7 +31,6 @@
size_t const target_count_;
};
-
CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
InstructionSequence* code, CompilationInfo* info)
: frame_access_state_(new (code->zone()) FrameAccessState(frame)),
@@ -45,6 +44,7 @@
resolver_(this),
safepoints_(code->zone()),
handlers_(code->zone()),
+ deoptimization_exits_(code->zone()),
deoptimization_states_(code->zone()),
deoptimization_literals_(code->zone()),
inlined_function_count_(0),
@@ -56,12 +56,8 @@
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
new (&labels_[i]) Label;
}
- if (code->ContainsCall()) {
- frame->MarkNeedsFrame();
- }
}
-
Handle<Code> CodeGenerator::GenerateCode() {
CompilationInfo* info = this->info();
@@ -80,14 +76,11 @@
}
// Architecture-specific, linkage-specific prologue.
info->set_prologue_offset(masm()->pc_offset());
- AssemblePrologue();
- if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) {
- masm()->InitializeRootRegister();
- }
// Define deoptimization literals for all inlined functions.
DCHECK_EQ(0u, deoptimization_literals_.size());
- for (auto& inlined : info->inlined_functions()) {
+ for (const CompilationInfo::InlinedFunctionHolder& inlined :
+ info->inlined_functions()) {
if (!inlined.shared_info.is_identical_to(info->shared_info())) {
DefineDeoptimizationLiteral(inlined.shared_info);
}
@@ -96,15 +89,19 @@
// 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()) {
+ for (const CompilationInfo::InlinedFunctionHolder& inlined :
+ info->inlined_functions()) {
if (!inlined.shared_info.is_identical_to(info->shared_info())) {
DefineDeoptimizationLiteral(inlined.inlined_code_object_root);
}
}
+ // Finish the Frame
+ frame()->AlignFrame(kFrameAlignmentInBytes);
+ AssembleSetupStackPointer();
// Assemble all non-deferred blocks, followed by deferred ones.
for (int deferred = 0; deferred < 2; ++deferred) {
- for (auto const block : code()->instruction_blocks()) {
+ for (const InstructionBlock* block : code()->instruction_blocks()) {
if (block->IsDeferred() == (deferred == 0)) {
continue;
}
@@ -141,9 +138,26 @@
SNPrintF(buffer, " --");
masm()->RecordComment(buffer_start);
}
+
+ frame_access_state()->MarkHasFrame(block->needs_frame());
+
masm()->bind(GetLabel(current_block_));
- for (int i = block->code_start(); i < block->code_end(); ++i) {
- AssembleInstruction(code()->InstructionAt(i));
+ if (block->must_construct_frame()) {
+ AssemblePrologue();
+ // We need to setup the root register after we assemble the prologue, to
+ // avoid clobbering callee saved registers in case of C linkage and
+ // using the roots.
+ // TODO(mtrofin): investigate how we can avoid doing this repeatedly.
+ if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) {
+ masm()->InitializeRootRegister();
+ }
+ }
+
+ if (FLAG_enable_embedded_constant_pool && !block->needs_frame()) {
+ ConstantPoolUnavailableScope constant_pool_unavailable(masm());
+ AssembleBlock(block);
+ } else {
+ AssembleBlock(block);
}
}
}
@@ -158,6 +172,12 @@
}
}
+ // Assemble all eager deoptimization exits.
+ for (DeoptimizationExit* exit : deoptimization_exits_) {
+ masm()->bind(exit->label());
+ AssembleDeoptimizerCall(exit->deoptimization_id(), Deoptimizer::EAGER);
+ }
+
// Ensure there is space for lazy deoptimization in the code.
if (info->ShouldEnsureSpaceForLazyDeopt()) {
int target_offset = masm()->pc_offset() + Deoptimizer::patch_size();
@@ -211,7 +231,8 @@
// Emit a code line info recording stop event.
void* line_info = recorder->DetachJITHandlerData();
- LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info));
+ LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(
+ AbstractCode::cast(*result), line_info));
return result;
}
@@ -232,7 +253,7 @@
safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode);
int stackSlotToSpillSlotDelta =
frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount();
- for (auto& operand : references->reference_operands()) {
+ for (const InstructionOperand& operand : references->reference_operands()) {
if (operand.IsStackSlot()) {
int index = LocationOperand::cast(operand).index();
DCHECK(index >= 0);
@@ -250,16 +271,15 @@
}
}
-
bool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object,
- int* offset_return) {
+ int* slot_return) {
if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
if (info()->has_context() && object.is_identical_to(info()->context()) &&
!info()->is_osr()) {
- *offset_return = StandardFrameConstants::kContextOffset;
+ *slot_return = Frame::kContextSlot;
return true;
} else if (object.is_identical_to(info()->closure())) {
- *offset_return = JavaScriptFrameConstants::kFunctionOffset;
+ *slot_return = Frame::kJSFunctionSlot;
return true;
}
}
@@ -282,43 +302,82 @@
return false;
}
+void CodeGenerator::AssembleBlock(const InstructionBlock* block) {
+ for (int i = block->code_start(); i < block->code_end(); ++i) {
+ Instruction* instr = code()->InstructionAt(i);
+ AssembleInstruction(instr, block);
+ }
+}
-void CodeGenerator::AssembleInstruction(Instruction* instr) {
+void CodeGenerator::AssembleInstruction(Instruction* instr,
+ const InstructionBlock* block) {
AssembleGaps(instr);
+ DCHECK_IMPLIES(
+ block->must_deconstruct_frame(),
+ instr != code()->InstructionAt(block->last_instruction_index()) ||
+ instr->IsRet() || instr->IsJump());
+ if (instr->IsJump() && block->must_deconstruct_frame()) {
+ AssembleDeconstructFrame();
+ }
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);
+ switch (mode) {
+ case 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);
+ if (true_rpo == false_rpo) {
+ // redundant branch.
+ if (!IsNextInAssemblyOrder(true_rpo)) {
+ AssembleArchJump(true_rpo);
+ }
+ return;
}
- 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);
+ break;
}
- if (IsNextInAssemblyOrder(true_rpo)) {
- // true block is next, can fall through if condition negated.
- std::swap(true_rpo, false_rpo);
- condition = NegateFlagsCondition(condition);
+ case kFlags_deoptimize: {
+ // Assemble a conditional eager deoptimization after this instruction.
+ InstructionOperandConverter i(this, instr);
+ size_t frame_state_offset = MiscField::decode(instr->opcode());
+ DeoptimizationExit* const exit =
+ AddDeoptimizationExit(instr, frame_state_offset);
+ Label continue_label;
+ BranchInfo branch;
+ branch.condition = condition;
+ branch.true_label = exit->label();
+ branch.false_label = &continue_label;
+ branch.fallthru = true;
+ // Assemble architecture-specific branch.
+ AssembleArchBranch(instr, &branch);
+ masm()->bind(&continue_label);
+ break;
}
- 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);
+ case kFlags_set: {
+ // Assemble a boolean materialization after this instruction.
+ AssembleArchBoolean(instr, condition);
+ break;
+ }
+ case kFlags_none: {
+ break;
+ }
}
}
@@ -595,6 +654,9 @@
shared_info_id,
static_cast<unsigned int>(descriptor->parameters_count()));
break;
+ case FrameStateType::kTailCallerFunction:
+ translation->BeginTailCallerFrame(shared_info_id);
+ break;
case FrameStateType::kConstructStub:
translation->BeginConstructStubFrame(
shared_info_id,
@@ -714,15 +776,22 @@
last_lazy_deopt_pc_ = masm()->pc_offset();
}
+DeoptimizationExit* CodeGenerator::AddDeoptimizationExit(
+ Instruction* instr, size_t frame_state_offset) {
+ int const deoptimization_id = BuildTranslation(
+ instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore());
+ DeoptimizationExit* const exit =
+ new (zone()) DeoptimizationExit(deoptimization_id);
+ deoptimization_exits_.push_back(exit);
+ return exit;
+}
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;
+ int sp_slot_delta = frame_access_state()->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;