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