Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h
index bdcd952..5cca888 100644
--- a/src/compiler/instruction-selector-impl.h
+++ b/src/compiler/instruction-selector-impl.h
@@ -8,12 +8,24 @@
#include "src/compiler/instruction.h"
#include "src/compiler/instruction-selector.h"
#include "src/compiler/linkage.h"
+#include "src/compiler/schedule.h"
#include "src/macro-assembler.h"
namespace v8 {
namespace internal {
namespace compiler {
+// Helper struct containing data about a table or lookup switch.
+struct SwitchInfo {
+ int32_t min_value; // minimum value of {case_values}
+ int32_t max_value; // maximum value of {case_values}
+ size_t value_range; // |max_value - min_value| + 1
+ size_t case_count; // number of cases
+ int32_t* case_values; // actual case values, unsorted
+ BasicBlock** case_branches; // basic blocks corresponding to case values
+ BasicBlock* default_branch; // default branch target
+};
+
// A helper class for the instruction selector that simplifies construction of
// Operands. This class implements a base for architecture-specific helpers.
class OperandGenerator {
@@ -21,132 +33,176 @@
explicit OperandGenerator(InstructionSelector* selector)
: selector_(selector) {}
- InstructionOperand* DefineAsRegister(Node* node) {
- return Define(node, new (zone())
- UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER));
+ InstructionOperand NoOutput() {
+ return InstructionOperand(); // Generates an invalid operand.
}
- InstructionOperand* DefineSameAsFirst(Node* result) {
- return Define(result, new (zone())
- UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT));
+ InstructionOperand DefineAsRegister(Node* node) {
+ return Define(node,
+ UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+ GetVReg(node)));
}
- InstructionOperand* DefineAsFixed(Node* node, Register reg) {
- return Define(node, new (zone())
- UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
- Register::ToAllocationIndex(reg)));
+ InstructionOperand DefineSameAsFirst(Node* node) {
+ return Define(node,
+ UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT,
+ GetVReg(node)));
}
- InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) {
- return Define(node, new (zone())
+ InstructionOperand DefineAsFixed(Node* node, Register reg) {
+ return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+ reg.code(), GetVReg(node)));
+ }
+
+ InstructionOperand DefineAsFixed(Node* node, DoubleRegister reg) {
+ return Define(node,
UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
- DoubleRegister::ToAllocationIndex(reg)));
+ reg.code(), GetVReg(node)));
}
- InstructionOperand* DefineAsConstant(Node* node) {
+ InstructionOperand DefineAsConstant(Node* node) {
selector()->MarkAsDefined(node);
- int virtual_register = selector_->GetVirtualRegister(node);
+ int virtual_register = GetVReg(node);
sequence()->AddConstant(virtual_register, ToConstant(node));
- return ConstantOperand::Create(virtual_register, zone());
+ return ConstantOperand(virtual_register);
}
- InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location,
- MachineType type) {
- return Define(node, ToUnallocatedOperand(location, type));
+ InstructionOperand DefineAsLocation(Node* node, LinkageLocation location,
+ MachineRepresentation rep) {
+ return Define(node, ToUnallocatedOperand(location, rep, GetVReg(node)));
}
- InstructionOperand* Use(Node* node) {
- return Use(
- node, new (zone()) UnallocatedOperand(
- UnallocatedOperand::NONE, UnallocatedOperand::USED_AT_START));
+ InstructionOperand DefineAsDualLocation(Node* node,
+ LinkageLocation primary_location,
+ LinkageLocation secondary_location) {
+ return Define(node,
+ ToDualLocationUnallocatedOperand(
+ primary_location, secondary_location, GetVReg(node)));
}
- InstructionOperand* UseRegister(Node* node) {
- return Use(node, new (zone())
- UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
- UnallocatedOperand::USED_AT_START));
+ InstructionOperand Use(Node* node) {
+ return Use(node, UnallocatedOperand(UnallocatedOperand::NONE,
+ UnallocatedOperand::USED_AT_START,
+ GetVReg(node)));
+ }
+
+ InstructionOperand UseAny(Node* node) {
+ return Use(node, UnallocatedOperand(UnallocatedOperand::ANY,
+ UnallocatedOperand::USED_AT_START,
+ GetVReg(node)));
+ }
+
+ InstructionOperand UseRegister(Node* node) {
+ return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+ UnallocatedOperand::USED_AT_START,
+ GetVReg(node)));
+ }
+
+ InstructionOperand UseUniqueSlot(Node* node) {
+ return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_SLOT,
+ GetVReg(node)));
}
// Use register or operand for the node. If a register is chosen, it won't
// alias any temporary or output registers.
- InstructionOperand* UseUnique(Node* node) {
- return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE));
+ InstructionOperand UseUnique(Node* node) {
+ return Use(node,
+ UnallocatedOperand(UnallocatedOperand::NONE, GetVReg(node)));
}
// Use a unique register for the node that does not alias any temporary or
// output registers.
- InstructionOperand* UseUniqueRegister(Node* node) {
- return Use(node, new (zone())
- UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER));
+ InstructionOperand UseUniqueRegister(Node* node) {
+ return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+ GetVReg(node)));
}
- InstructionOperand* UseFixed(Node* node, Register reg) {
- return Use(node, new (zone())
- UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
- Register::ToAllocationIndex(reg)));
+ InstructionOperand UseFixed(Node* node, Register reg) {
+ return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+ reg.code(), GetVReg(node)));
}
- InstructionOperand* UseFixed(Node* node, DoubleRegister reg) {
- return Use(node, new (zone())
+ InstructionOperand UseFixed(Node* node, DoubleRegister reg) {
+ return Use(node,
UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
- DoubleRegister::ToAllocationIndex(reg)));
+ reg.code(), GetVReg(node)));
}
- InstructionOperand* UseImmediate(Node* node) {
- int index = sequence()->AddImmediate(ToConstant(node));
- return ImmediateOperand::Create(index, zone());
+ InstructionOperand UseExplicit(LinkageLocation location) {
+ MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
+ if (location.IsRegister()) {
+ return ExplicitOperand(LocationOperand::REGISTER, rep,
+ location.AsRegister());
+ } else {
+ return ExplicitOperand(LocationOperand::STACK_SLOT, rep,
+ location.GetLocation());
+ }
}
- InstructionOperand* UseLocation(Node* node, LinkageLocation location,
- MachineType type) {
- return Use(node, ToUnallocatedOperand(location, type));
+ InstructionOperand UseImmediate(Node* node) {
+ return sequence()->AddImmediate(ToConstant(node));
}
- InstructionOperand* TempRegister() {
- UnallocatedOperand* op =
- new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
- UnallocatedOperand::USED_AT_START);
- op->set_virtual_register(sequence()->NextVirtualRegister());
+ InstructionOperand UseLocation(Node* node, LinkageLocation location,
+ MachineRepresentation rep) {
+ return Use(node, ToUnallocatedOperand(location, rep, GetVReg(node)));
+ }
+
+ // Used to force gap moves from the from_location to the to_location
+ // immediately before an instruction.
+ InstructionOperand UsePointerLocation(LinkageLocation to_location,
+ LinkageLocation from_location) {
+ MachineRepresentation rep = MachineType::PointerRepresentation();
+ UnallocatedOperand casted_from_operand =
+ UnallocatedOperand::cast(TempLocation(from_location, rep));
+ selector_->Emit(kArchNop, casted_from_operand);
+ return ToUnallocatedOperand(to_location, rep,
+ casted_from_operand.virtual_register());
+ }
+
+ InstructionOperand TempRegister() {
+ return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+ UnallocatedOperand::USED_AT_START,
+ sequence()->NextVirtualRegister());
+ }
+
+ InstructionOperand TempDoubleRegister() {
+ UnallocatedOperand op = UnallocatedOperand(
+ UnallocatedOperand::MUST_HAVE_REGISTER,
+ UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister());
+ sequence()->MarkAsRepresentation(MachineRepresentation::kFloat64,
+ op.virtual_register());
return op;
}
- InstructionOperand* TempDoubleRegister() {
- UnallocatedOperand* op =
- new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
- UnallocatedOperand::USED_AT_START);
- op->set_virtual_register(sequence()->NextVirtualRegister());
- sequence()->MarkAsDouble(op->virtual_register());
- return op;
+ InstructionOperand TempRegister(Register reg) {
+ return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, reg.code(),
+ InstructionOperand::kInvalidVirtualRegister);
}
- InstructionOperand* TempRegister(Register reg) {
- return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
- Register::ToAllocationIndex(reg));
+ InstructionOperand TempImmediate(int32_t imm) {
+ return sequence()->AddImmediate(Constant(imm));
}
- InstructionOperand* TempImmediate(int32_t imm) {
- int index = sequence()->AddImmediate(Constant(imm));
- return ImmediateOperand::Create(index, zone());
+ InstructionOperand TempLocation(LinkageLocation location,
+ MachineRepresentation rep) {
+ return ToUnallocatedOperand(location, rep,
+ sequence()->NextVirtualRegister());
}
- InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
- UnallocatedOperand* op = ToUnallocatedOperand(location, type);
- op->set_virtual_register(sequence()->NextVirtualRegister());
- return op;
- }
-
- InstructionOperand* Label(BasicBlock* block) {
- int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
- return ImmediateOperand::Create(index, zone());
+ InstructionOperand Label(BasicBlock* block) {
+ return sequence()->AddImmediate(
+ Constant(RpoNumber::FromInt(block->rpo_number())));
}
protected:
InstructionSelector* selector() const { return selector_; }
InstructionSequence* sequence() const { return selector()->sequence(); }
- Isolate* isolate() const { return zone()->isolate(); }
Zone* zone() const { return selector()->instruction_zone(); }
private:
+ int GetVReg(Node* node) const { return selector_->GetVirtualRegister(node); }
+
static Constant ToConstant(const Node* node) {
switch (node->opcode()) {
case IrOpcode::kInt32Constant:
@@ -161,7 +217,7 @@
case IrOpcode::kExternalConstant:
return Constant(OpParameter<ExternalReference>(node));
case IrOpcode::kHeapConstant:
- return Constant(OpParameter<Unique<HeapObject> >(node).handle());
+ return Constant(OpParameter<Handle<HeapObject>>(node));
default:
break;
}
@@ -169,38 +225,57 @@
return Constant(static_cast<int32_t>(0));
}
- UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) {
+ UnallocatedOperand Define(Node* node, UnallocatedOperand operand) {
DCHECK_NOT_NULL(node);
- DCHECK_NOT_NULL(operand);
- operand->set_virtual_register(selector_->GetVirtualRegister(node));
+ DCHECK_EQ(operand.virtual_register(), GetVReg(node));
selector()->MarkAsDefined(node);
return operand;
}
- UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) {
+ UnallocatedOperand Use(Node* node, UnallocatedOperand operand) {
DCHECK_NOT_NULL(node);
- DCHECK_NOT_NULL(operand);
- operand->set_virtual_register(selector_->GetVirtualRegister(node));
+ DCHECK_EQ(operand.virtual_register(), GetVReg(node));
selector()->MarkAsUsed(node);
return operand;
}
- UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location,
- MachineType type) {
- if (location.location_ == LinkageLocation::ANY_REGISTER) {
- return new (zone())
- UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER);
+ UnallocatedOperand ToDualLocationUnallocatedOperand(
+ LinkageLocation primary_location, LinkageLocation secondary_location,
+ int virtual_register) {
+ // We only support the primary location being a register and the secondary
+ // one a slot.
+ DCHECK(primary_location.IsRegister() &&
+ secondary_location.IsCalleeFrameSlot());
+ int reg_id = primary_location.AsRegister();
+ int slot_id = secondary_location.AsCalleeFrameSlot();
+ return UnallocatedOperand(reg_id, slot_id, virtual_register);
+ }
+
+ UnallocatedOperand ToUnallocatedOperand(LinkageLocation location,
+ MachineRepresentation rep,
+ int virtual_register) {
+ if (location.IsAnyRegister()) {
+ // any machine register.
+ return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+ virtual_register);
}
- if (location.location_ < 0) {
- return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
- location.location_);
+ if (location.IsCallerFrameSlot()) {
+ // a location on the caller frame.
+ return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
+ location.AsCallerFrameSlot(), virtual_register);
}
- if (RepresentationOf(type) == kRepFloat64) {
- return new (zone()) UnallocatedOperand(
- UnallocatedOperand::FIXED_DOUBLE_REGISTER, location.location_);
+ if (location.IsCalleeFrameSlot()) {
+ // a spill location on this (callee) frame.
+ return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
+ location.AsCalleeFrameSlot(), virtual_register);
}
- return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
- location.location_);
+ // a fixed register.
+ if (IsFloatingPoint(rep)) {
+ return UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
+ location.AsRegister(), virtual_register);
+ }
+ return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+ location.AsRegister(), virtual_register);
}
InstructionSelector* selector_;
@@ -212,7 +287,7 @@
// The whole instruction is treated as a unit by the register allocator, and
// thus no spills or moves can be introduced between the flags-setting
// instruction and the branch or set it should be combined with.
-class FlagsContinuation FINAL {
+class FlagsContinuation final {
public:
FlagsContinuation() : mode_(kFlags_none) {}
@@ -261,53 +336,7 @@
void Commute() {
DCHECK(!IsNone());
- switch (condition_) {
- case kEqual:
- case kNotEqual:
- case kOverflow:
- case kNotOverflow:
- return;
- case kSignedLessThan:
- condition_ = kSignedGreaterThan;
- return;
- case kSignedGreaterThanOrEqual:
- condition_ = kSignedLessThanOrEqual;
- return;
- case kSignedLessThanOrEqual:
- condition_ = kSignedGreaterThanOrEqual;
- return;
- case kSignedGreaterThan:
- condition_ = kSignedLessThan;
- return;
- case kUnsignedLessThan:
- condition_ = kUnsignedGreaterThan;
- return;
- case kUnsignedGreaterThanOrEqual:
- condition_ = kUnsignedLessThanOrEqual;
- return;
- case kUnsignedLessThanOrEqual:
- condition_ = kUnsignedGreaterThanOrEqual;
- return;
- case kUnsignedGreaterThan:
- condition_ = kUnsignedLessThan;
- return;
- case kUnorderedEqual:
- case kUnorderedNotEqual:
- return;
- case kUnorderedLessThan:
- condition_ = kUnorderedGreaterThan;
- return;
- case kUnorderedGreaterThanOrEqual:
- condition_ = kUnorderedLessThanOrEqual;
- return;
- case kUnorderedLessThanOrEqual:
- condition_ = kUnorderedGreaterThanOrEqual;
- return;
- case kUnorderedGreaterThan:
- condition_ = kUnorderedLessThan;
- return;
- }
- UNREACHABLE();
+ condition_ = CommuteFlagsCondition(condition_);
}
void OverwriteAndNegateIfEqual(FlagsCondition condition) {
@@ -333,33 +362,6 @@
BasicBlock* false_block_; // Only valid if mode_ == kFlags_branch.
};
-
-// An internal helper class for generating the operands to calls.
-// TODO(bmeurer): Get rid of the CallBuffer business and make
-// InstructionSelector::VisitCall platform independent instead.
-struct CallBuffer {
- CallBuffer(Zone* zone, const CallDescriptor* descriptor,
- FrameStateDescriptor* frame_state);
-
- const CallDescriptor* descriptor;
- FrameStateDescriptor* frame_state_descriptor;
- NodeVector output_nodes;
- InstructionOperandVector outputs;
- InstructionOperandVector instruction_args;
- NodeVector pushed_nodes;
-
- size_t input_count() const { return descriptor->InputCount(); }
-
- size_t frame_state_count() const { return descriptor->FrameStateCount(); }
-
- size_t frame_state_value_count() const {
- return (frame_state_descriptor == NULL)
- ? 0
- : (frame_state_descriptor->GetTotalSize() +
- 1); // Include deopt id.
- }
-};
-
} // namespace compiler
} // namespace internal
} // namespace v8