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/linkage.h b/src/compiler/linkage.h
index 0ad0761..252f044 100644
--- a/src/compiler/linkage.h
+++ b/src/compiler/linkage.h
@@ -7,68 +7,175 @@
 
 #include "src/base/flags.h"
 #include "src/compiler/frame.h"
-#include "src/compiler/machine-type.h"
 #include "src/compiler/operator.h"
+#include "src/frames.h"
+#include "src/machine-type.h"
+#include "src/runtime/runtime.h"
 #include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 
 class CallInterfaceDescriptor;
+class CompilationInfo;
 
 namespace compiler {
 
+const RegList kNoCalleeSaved = 0;
+
+class Node;
+class OsrHelper;
+
 // Describes the location for a parameter or a return value to a call.
 class LinkageLocation {
  public:
-  explicit LinkageLocation(int location) : location_(location) {}
+  bool operator==(const LinkageLocation& other) const {
+    return bit_field_ == other.bit_field_;
+  }
 
-  static const int16_t ANY_REGISTER = 32767;
+  bool operator!=(const LinkageLocation& other) const {
+    return !(*this == other);
+  }
 
-  static LinkageLocation AnyRegister() { return LinkageLocation(ANY_REGISTER); }
+  static LinkageLocation ForAnyRegister() {
+    return LinkageLocation(REGISTER, ANY_REGISTER);
+  }
+
+  static LinkageLocation ForRegister(int32_t reg) {
+    DCHECK(reg >= 0);
+    return LinkageLocation(REGISTER, reg);
+  }
+
+  static LinkageLocation ForCallerFrameSlot(int32_t slot) {
+    DCHECK(slot < 0);
+    return LinkageLocation(STACK_SLOT, slot);
+  }
+
+  static LinkageLocation ForCalleeFrameSlot(int32_t slot) {
+    // TODO(titzer): bailout instead of crashing here.
+    DCHECK(slot >= 0 && slot < LinkageLocation::MAX_STACK_SLOT);
+    return LinkageLocation(STACK_SLOT, slot);
+  }
+
+  static LinkageLocation ForSavedCallerReturnAddress() {
+    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
+                               StandardFrameConstants::kCallerPCOffset) /
+                              kPointerSize);
+  }
+
+  static LinkageLocation ForSavedCallerFramePtr() {
+    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
+                               StandardFrameConstants::kCallerFPOffset) /
+                              kPointerSize);
+  }
+
+  static LinkageLocation ForSavedCallerConstantPool() {
+    DCHECK(V8_EMBEDDED_CONSTANT_POOL);
+    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
+                               StandardFrameConstants::kConstantPoolOffset) /
+                              kPointerSize);
+  }
+
+  static LinkageLocation ConvertToTailCallerLocation(
+      LinkageLocation caller_location, int stack_param_delta) {
+    if (!caller_location.IsRegister()) {
+      return LinkageLocation(STACK_SLOT,
+                             caller_location.GetLocation() - stack_param_delta);
+    }
+    return caller_location;
+  }
 
  private:
   friend class CallDescriptor;
   friend class OperandGenerator;
-  int16_t location_;  // >= 0 implies register, otherwise stack slot.
+
+  enum LocationType { REGISTER, STACK_SLOT };
+
+  class TypeField : public BitField<LocationType, 0, 1> {};
+  class LocationField : public BitField<int32_t, TypeField::kNext, 31> {};
+
+  static const int32_t ANY_REGISTER = -1;
+  static const int32_t MAX_STACK_SLOT = 32767;
+
+  LinkageLocation(LocationType type, int32_t location) {
+    bit_field_ = TypeField::encode(type) |
+                 ((location << LocationField::kShift) & LocationField::kMask);
+  }
+
+  int32_t GetLocation() const {
+    return static_cast<int32_t>(bit_field_ & LocationField::kMask) >>
+           LocationField::kShift;
+  }
+
+  bool IsRegister() const { return TypeField::decode(bit_field_) == REGISTER; }
+  bool IsAnyRegister() const {
+    return IsRegister() && GetLocation() == ANY_REGISTER;
+  }
+  bool IsCallerFrameSlot() const { return !IsRegister() && GetLocation() < 0; }
+  bool IsCalleeFrameSlot() const { return !IsRegister() && GetLocation() >= 0; }
+
+  int32_t AsRegister() const {
+    DCHECK(IsRegister());
+    return GetLocation();
+  }
+  int32_t AsCallerFrameSlot() const {
+    DCHECK(IsCallerFrameSlot());
+    return GetLocation();
+  }
+  int32_t AsCalleeFrameSlot() const {
+    DCHECK(IsCalleeFrameSlot());
+    return GetLocation();
+  }
+
+  int32_t bit_field_;
 };
 
 typedef Signature<LinkageLocation> LocationSignature;
 
 // Describes a call to various parts of the compiler. Every call has the notion
 // of a "target", which is the first input to the call.
-class CallDescriptor FINAL : public ZoneObject {
+class CallDescriptor final : public ZoneObject {
  public:
   // Describes the kind of this call, which determines the target.
   enum Kind {
     kCallCodeObject,  // target is a Code object
     kCallJSFunction,  // target is a JSFunction object
-    kCallAddress      // target is a machine pointer
+    kCallAddress,     // target is a machine pointer
+    kLazyBailout      // the call is no-op, only used for lazy bailout
   };
 
   enum Flag {
-    // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be unified.
     kNoFlags = 0u,
     kNeedsFrameState = 1u << 0,
     kPatchableCallSite = 1u << 1,
     kNeedsNopAfterCall = 1u << 2,
+    kHasExceptionHandler = 1u << 3,
+    kHasLocalCatchHandler = 1u << 4,
+    kSupportsTailCalls = 1u << 5,
+    kCanUseRoots = 1u << 6,
+    // Indicates that the native stack should be used for a code object. This
+    // information is important for native calls on arm64.
+    kUseNativeStack = 1u << 7,
     kPatchableCallSiteWithNop = kPatchableCallSite | kNeedsNopAfterCall
   };
   typedef base::Flags<Flag> Flags;
 
   CallDescriptor(Kind kind, MachineType target_type, LinkageLocation target_loc,
-                 MachineSignature* machine_sig, LocationSignature* location_sig,
-                 size_t js_param_count, Operator::Properties properties,
-                 RegList callee_saved_registers, Flags flags,
+                 const MachineSignature* machine_sig,
+                 LocationSignature* location_sig, size_t stack_param_count,
+                 Operator::Properties properties,
+                 RegList callee_saved_registers,
+                 RegList callee_saved_fp_registers, Flags flags,
                  const char* debug_name = "")
       : kind_(kind),
         target_type_(target_type),
         target_loc_(target_loc),
         machine_sig_(machine_sig),
         location_sig_(location_sig),
-        js_param_count_(js_param_count),
+        stack_param_count_(stack_param_count),
         properties_(properties),
         callee_saved_registers_(callee_saved_registers),
+        callee_saved_fp_registers_(callee_saved_fp_registers),
         flags_(flags),
         debug_name_(debug_name) {
     DCHECK(machine_sig->return_count() == location_sig->return_count());
@@ -78,15 +185,30 @@
   // Returns the kind of this call.
   Kind kind() const { return kind_; }
 
+  // Returns {true} if this descriptor is a call to a C function.
+  bool IsCFunctionCall() const { return kind_ == kCallAddress; }
+
   // Returns {true} if this descriptor is a call to a JSFunction.
   bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; }
 
+  bool RequiresFrameAsIncoming() const {
+    return IsCFunctionCall() || IsJSFunctionCall();
+  }
+
   // The number of return values from this call.
   size_t ReturnCount() const { return machine_sig_->return_count(); }
 
-  // The number of JavaScript parameters to this call, including the receiver
-  // object.
-  size_t JSParameterCount() const { return js_param_count_; }
+  // The number of C parameters to this call.
+  size_t CParameterCount() const { return machine_sig_->parameter_count(); }
+
+  // The number of stack parameters to the call.
+  size_t StackParameterCount() const { return stack_param_count_; }
+
+  // The number of parameters to the JS function call.
+  size_t JSParameterCount() const {
+    DCHECK(IsJSFunctionCall());
+    return stack_param_count_;
+  }
 
   // The total number of inputs to this call, which includes the target,
   // receiver, context, etc.
@@ -98,6 +220,8 @@
   Flags flags() const { return flags_; }
 
   bool NeedsFrameState() const { return flags() & kNeedsFrameState; }
+  bool SupportsTailCalls() const { return flags() & kSupportsTailCalls; }
+  bool UseNativeStack() const { return flags() & kUseNativeStack; }
 
   LinkageLocation GetReturnLocation(size_t index) const {
     return location_sig_->GetReturn(index);
@@ -125,8 +249,17 @@
   // Get the callee-saved registers, if any, across this call.
   RegList CalleeSavedRegisters() const { return callee_saved_registers_; }
 
+  // Get the callee-saved FP registers, if any, across this call.
+  RegList CalleeSavedFPRegisters() const { return callee_saved_fp_registers_; }
+
   const char* debug_name() const { return debug_name_; }
 
+  bool UsesOnlyRegisters() const;
+
+  bool HasSameReturnLocationsAs(const CallDescriptor* other) const;
+
+  bool CanTailCall(const Node* call, int* stack_param_delta) const;
+
  private:
   friend class Linkage;
 
@@ -135,9 +268,10 @@
   const LinkageLocation target_loc_;
   const MachineSignature* const machine_sig_;
   const LocationSignature* const location_sig_;
-  const size_t js_param_count_;
+  const size_t stack_param_count_;
   const Operator::Properties properties_;
   const RegList callee_saved_registers_;
+  const RegList callee_saved_fp_registers_;
   const Flags flags_;
   const char* const debug_name_;
 
@@ -156,49 +290,49 @@
 // Can be used to translate {arg_index} (i.e. index of the call node input) as
 // well as {param_index} (i.e. as stored in parameter nodes) into an operator
 // representing the architecture-specific location. The following call node
-// layouts are supported (where {n} is the number value inputs):
+// layouts are supported (where {n} is the number of value inputs):
 //
 //                  #0          #1     #2     #3     [...]             #n
 // Call[CodeStub]   code,       arg 1, arg 2, arg 3, [...],            context
-// Call[JSFunction] function,   rcvr,  arg 1, arg 2, [...],            context
+// Call[JSFunction] function,   rcvr,  arg 1, arg 2, [...], new, #arg, context
 // Call[Runtime]    CEntryStub, arg 1, arg 2, arg 3, [...], fun, #arg, context
 class Linkage : public ZoneObject {
  public:
-  Linkage(Zone* zone, CompilationInfo* info)
-      : zone_(zone), incoming_(ComputeIncoming(zone, info)) {}
-  Linkage(Zone* zone, CallDescriptor* incoming)
-      : zone_(zone), incoming_(incoming) {}
+  explicit Linkage(CallDescriptor* incoming) : incoming_(incoming) {}
 
   static CallDescriptor* ComputeIncoming(Zone* zone, CompilationInfo* info);
 
   // The call descriptor for this compilation unit describes the locations
   // of incoming parameters and the outgoing return value(s).
   CallDescriptor* GetIncomingDescriptor() const { return incoming_; }
-  CallDescriptor* GetJSCallDescriptor(int parameter_count,
-                                      CallDescriptor::Flags flags) const;
-  static CallDescriptor* GetJSCallDescriptor(int parameter_count, Zone* zone,
+  static CallDescriptor* GetJSCallDescriptor(Zone* zone, bool is_osr,
+                                             int parameter_count,
                                              CallDescriptor::Flags flags);
-  CallDescriptor* GetRuntimeCallDescriptor(
-      Runtime::FunctionId function, int parameter_count,
-      Operator::Properties properties) const;
-  static CallDescriptor* GetRuntimeCallDescriptor(
-      Runtime::FunctionId function, int parameter_count,
-      Operator::Properties properties, Zone* zone);
 
-  CallDescriptor* GetStubCallDescriptor(
-      const CallInterfaceDescriptor& descriptor, int stack_parameter_count = 0,
-      CallDescriptor::Flags flags = CallDescriptor::kNoFlags,
-      Operator::Properties properties = Operator::kNoProperties) const;
+  static CallDescriptor* GetRuntimeCallDescriptor(
+      Zone* zone, Runtime::FunctionId function, int parameter_count,
+      Operator::Properties properties, CallDescriptor::Flags flags);
+
+  static CallDescriptor* GetLazyBailoutDescriptor(Zone* zone);
+
   static CallDescriptor* GetStubCallDescriptor(
-      const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-      CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone);
+      Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
+      int stack_parameter_count, CallDescriptor::Flags flags,
+      Operator::Properties properties = Operator::kNoProperties,
+      MachineType return_type = MachineType::AnyTagged(),
+      size_t return_count = 1);
 
   // Creates a call descriptor for simplified C calls that is appropriate
   // for the host platform. This simplified calling convention only supports
   // integers and pointers of one word size each, i.e. no floating point,
   // structs, pointers to members, etc.
   static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig);
+                                                  const MachineSignature* sig);
+
+  // Creates a call descriptor for interpreter handler code stubs. These are not
+  // intended to be called directly but are instead dispatched to by the
+  // interpreter.
+  static CallDescriptor* GetInterpreterDispatchDescriptor(Zone* zone);
 
   // Get the location of an (incoming) parameter to this function.
   LinkageLocation GetParameterLocation(int index) const {
@@ -211,24 +345,54 @@
   }
 
   // Get the location where this function should place its return value.
-  LinkageLocation GetReturnLocation() const {
-    return incoming_->GetReturnLocation(0);
+  LinkageLocation GetReturnLocation(size_t index = 0) const {
+    return incoming_->GetReturnLocation(index);
   }
 
   // Get the machine type of this function's return value.
-  MachineType GetReturnType() const { return incoming_->GetReturnType(0); }
+  MachineType GetReturnType(size_t index = 0) const {
+    return incoming_->GetReturnType(index);
+  }
 
-  // Get the frame offset for a given spill slot. The location depends on the
-  // calling convention and the specific frame layout, and may thus be
-  // architecture-specific. Negative spill slots indicate arguments on the
-  // caller's frame. The {extra} parameter indicates an additional offset from
-  // the frame offset, e.g. to index into part of a double slot.
-  FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0) const;
+  bool ParameterHasSecondaryLocation(int index) const;
+  LinkageLocation GetParameterSecondaryLocation(int index) const;
 
-  static bool NeedsFrameState(Runtime::FunctionId function);
+  static int FrameStateInputCount(Runtime::FunctionId function);
+
+  // Get the location where an incoming OSR value is stored.
+  LinkageLocation GetOsrValueLocation(int index) const;
+
+  // A special {Parameter} index for JSCalls that represents the new target.
+  static int GetJSCallNewTargetParamIndex(int parameter_count) {
+    return parameter_count + 0;  // Parameter (arity + 0) is special.
+  }
+
+  // A special {Parameter} index for JSCalls that represents the argument count.
+  static int GetJSCallArgCountParamIndex(int parameter_count) {
+    return parameter_count + 1;  // Parameter (arity + 1) is special.
+  }
+
+  // A special {Parameter} index for JSCalls that represents the context.
+  static int GetJSCallContextParamIndex(int parameter_count) {
+    return parameter_count + 2;  // Parameter (arity + 2) is special.
+  }
+
+  // A special {Parameter} index for JSCalls that represents the closure.
+  static const int kJSCallClosureParamIndex = -1;
+
+  // A special {OsrValue} index to indicate the context spill slot.
+  static const int kOsrContextSpillSlotIndex = -1;
+
+  // Special parameter indices used to pass fixed register data through
+  // interpreter dispatches.
+  static const int kInterpreterAccumulatorParameter = 0;
+  static const int kInterpreterRegisterFileParameter = 1;
+  static const int kInterpreterBytecodeOffsetParameter = 2;
+  static const int kInterpreterBytecodeArrayParameter = 3;
+  static const int kInterpreterDispatchTableParameter = 4;
+  static const int kInterpreterContextParameter = 5;
 
  private:
-  Zone* const zone_;
   CallDescriptor* const incoming_;
 
   DISALLOW_COPY_AND_ASSIGN(Linkage);