Merge V8 5.2.361.47  DO NOT MERGE

https://chromium.googlesource.com/v8/v8/+/5.2.361.47

FPIIM-449

Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/interpreter/bytecode-traits.h b/src/interpreter/bytecode-traits.h
index c724827..e7d1432 100644
--- a/src/interpreter/bytecode-traits.h
+++ b/src/interpreter/bytecode-traits.h
@@ -41,6 +41,28 @@
 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
 #undef DECLARE_OPERAND_TYPE_TRAITS
 
+template <OperandType operand_type, OperandScale operand_scale>
+struct OperandScaler {
+  template <bool, OperandSize, OperandScale>
+  struct Helper {
+    static const int kSize = 0;
+  };
+  template <OperandSize size, OperandScale scale>
+  struct Helper<false, size, scale> {
+    static const int kSize = static_cast<int>(size);
+  };
+  template <OperandSize size, OperandScale scale>
+  struct Helper<true, size, scale> {
+    static const int kSize = static_cast<int>(size) * static_cast<int>(scale);
+  };
+
+  static const int kSize =
+      Helper<OperandTraits<operand_type>::TypeInfo::kIsScalable,
+             OperandTraits<operand_type>::TypeInfo::kUnscaledSize,
+             operand_scale>::kSize;
+  static const OperandSize kOperandSize = static_cast<OperandSize>(kSize);
+};
+
 template <OperandType>
 struct RegisterOperandTraits {
   static const int kIsRegisterOperand = 0;
@@ -61,11 +83,30 @@
           OperandType operand_1, OperandType operand_2, OperandType operand_3>
 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2,
                       operand_3> {
-  static OperandType GetOperandType(int i) {
-    DCHECK(0 <= i && i < kOperandCount);
-    const OperandType kOperands[] = {operand_0, operand_1, operand_2,
-                                     operand_3};
-    return kOperands[i];
+  static const OperandType* GetOperandTypes() {
+    static const OperandType operand_types[] = {operand_0, operand_1, operand_2,
+                                                operand_3, OperandType::kNone};
+    return operand_types;
+  }
+
+  static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
+    switch (operand_scale) {
+#define CASE(Name, _)                                                  \
+  case OperandScale::k##Name: {                                        \
+    static const OperandSize kOperandSizes[] = {                       \
+        OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
+        OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \
+        OperandScaler<operand_2, OperandScale::k##Name>::kOperandSize, \
+        OperandScaler<operand_3, OperandScale::k##Name>::kOperandSize, \
+    };                                                                 \
+    DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes));       \
+    return kOperandSizes[i];                                           \
+  }
+      OPERAND_SCALE_LIST(CASE)
+#undef CASE
+    }
+    UNREACHABLE();
+    return OperandSize::kNone;
   }
 
   template <OperandType ot>
@@ -98,10 +139,29 @@
 template <AccumulatorUse accumulator_use, OperandType operand_0,
           OperandType operand_1, OperandType operand_2>
 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> {
-  static inline OperandType GetOperandType(int i) {
-    DCHECK(0 <= i && i <= 2);
-    const OperandType kOperands[] = {operand_0, operand_1, operand_2};
-    return kOperands[i];
+  static const OperandType* GetOperandTypes() {
+    static const OperandType operand_types[] = {operand_0, operand_1, operand_2,
+                                                OperandType::kNone};
+    return operand_types;
+  }
+
+  static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
+    switch (operand_scale) {
+#define CASE(Name, _)                                                  \
+  case OperandScale::k##Name: {                                        \
+    static const OperandSize kOperandSizes[] = {                       \
+        OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
+        OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \
+        OperandScaler<operand_2, OperandScale::k##Name>::kOperandSize, \
+    };                                                                 \
+    DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes));       \
+    return kOperandSizes[i];                                           \
+  }
+      OPERAND_SCALE_LIST(CASE)
+#undef CASE
+    }
+    UNREACHABLE();
+    return OperandSize::kNone;
   }
 
   template <OperandType ot>
@@ -130,10 +190,28 @@
 template <AccumulatorUse accumulator_use, OperandType operand_0,
           OperandType operand_1>
 struct BytecodeTraits<accumulator_use, operand_0, operand_1> {
-  static inline OperandType GetOperandType(int i) {
-    DCHECK(0 <= i && i < kOperandCount);
-    const OperandType kOperands[] = {operand_0, operand_1};
-    return kOperands[i];
+  static const OperandType* GetOperandTypes() {
+    static const OperandType operand_types[] = {operand_0, operand_1,
+                                                OperandType::kNone};
+    return operand_types;
+  }
+
+  static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
+    switch (operand_scale) {
+#define CASE(Name, _)                                                  \
+  case OperandScale::k##Name: {                                        \
+    static const OperandSize kOperandSizes[] = {                       \
+        OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
+        OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \
+    };                                                                 \
+    DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes));       \
+    return kOperandSizes[i];                                           \
+  }
+      OPERAND_SCALE_LIST(CASE)
+#undef CASE
+    }
+    UNREACHABLE();
+    return OperandSize::kNone;
   }
 
   template <OperandType ot>
@@ -158,9 +236,26 @@
 
 template <AccumulatorUse accumulator_use, OperandType operand_0>
 struct BytecodeTraits<accumulator_use, operand_0> {
-  static inline OperandType GetOperandType(int i) {
-    DCHECK(i == 0);
-    return operand_0;
+  static const OperandType* GetOperandTypes() {
+    static const OperandType operand_types[] = {operand_0, OperandType::kNone};
+    return operand_types;
+  }
+
+  static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
+    switch (operand_scale) {
+#define CASE(Name, _)                                                  \
+  case OperandScale::k##Name: {                                        \
+    static const OperandSize kOperandSizes[] = {                       \
+        OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
+    };                                                                 \
+    DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes));       \
+    return kOperandSizes[i];                                           \
+  }
+      OPERAND_SCALE_LIST(CASE)
+#undef CASE
+    }
+    UNREACHABLE();
+    return OperandSize::kNone;
   }
 
   template <OperandType ot>
@@ -182,9 +277,14 @@
 
 template <AccumulatorUse accumulator_use>
 struct BytecodeTraits<accumulator_use> {
-  static inline OperandType GetOperandType(int i) {
+  static const OperandType* GetOperandTypes() {
+    static const OperandType operand_types[] = {OperandType::kNone};
+    return operand_types;
+  }
+
+  static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
     UNREACHABLE();
-    return OperandType::kNone;
+    return OperandSize::kNone;
   }
 
   template <OperandType ot>
@@ -200,37 +300,22 @@
   static const int kRegisterOperandBitmap = 0;
 };
 
-template <bool>
-struct OperandScaler {
-  static int Multiply(int size, int operand_scale) { return 0; }
-};
-
-template <>
-struct OperandScaler<false> {
-  static int Multiply(int size, int operand_scale) { return size; }
-};
-
-template <>
-struct OperandScaler<true> {
-  static int Multiply(int size, int operand_scale) {
-    return size * operand_scale;
-  }
-};
-
 static OperandSize ScaledOperandSize(OperandType operand_type,
                                      OperandScale operand_scale) {
+  STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
+                OperandScale::kLast == OperandScale::kQuadruple);
+  int index = static_cast<int>(operand_scale) >> 1;
   switch (operand_type) {
-#define CASE(Name, TypeInfo)                                                   \
-  case OperandType::k##Name: {                                                 \
-    OperandSize base_size = OperandTypeInfoTraits<TypeInfo>::kUnscaledSize;    \
-    int size =                                                                 \
-        OperandScaler<OperandTypeInfoTraits<TypeInfo>::kIsScalable>::Multiply( \
-            static_cast<int>(base_size), static_cast<int>(operand_scale));     \
-    OperandSize operand_size = static_cast<OperandSize>(size);                 \
-    DCHECK(operand_size == OperandSize::kByte ||                               \
-           operand_size == OperandSize::kShort ||                              \
-           operand_size == OperandSize::kQuad);                                \
-    return operand_size;                                                       \
+#define CASE(Name, TypeInfo)                                    \
+  case OperandType::k##Name: {                                  \
+    static const OperandSize kOperandSizes[] = {                \
+        OperandScaler<OperandType::k##Name,                     \
+                      OperandScale::kSingle>::kOperandSize,     \
+        OperandScaler<OperandType::k##Name,                     \
+                      OperandScale::kDouble>::kOperandSize,     \
+        OperandScaler<OperandType::k##Name,                     \
+                      OperandScale::kQuadruple>::kOperandSize}; \
+    return kOperandSizes[index];                                \
   }
     OPERAND_TYPE_LIST(CASE)
 #undef CASE