Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index fbc064c..81d4cd0 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -15,7 +15,6 @@
 #include "src/compiler/node-matchers.h"
 #include "src/field-index-inl.h"
 #include "src/isolate-inl.h"
-#include "src/objects-inl.h"  // TODO(mstarzinger): Temporary cycle breaker!
 #include "src/type-cache.h"
 #include "src/type-feedback-vector.h"
 
@@ -79,9 +78,9 @@
          node->opcode() == IrOpcode::kJSLoadProperty ||
          node->opcode() == IrOpcode::kJSStoreProperty);
   Node* receiver = NodeProperties::GetValueInput(node, 0);
-  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
   Node* effect = NodeProperties::GetEffectInput(node);
   Node* control = NodeProperties::GetControlInput(node);
+  Node* frame_state = NodeProperties::FindFrameStateBefore(node);
 
   // Not much we can do if deoptimization support is disabled.
   if (!(flags() & kDeoptimizationEnabled)) return NoChange();
@@ -112,8 +111,8 @@
   if (index != nullptr) {
     Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Name()),
                                    index, jsgraph()->HeapConstant(name));
-    control = graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
-                               effect, control);
+    control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check,
+                                        frame_state, effect, control);
   }
 
   // Check if {receiver} may be a number.
@@ -126,17 +125,17 @@
   }
 
   // Ensure that {receiver} is a heap object.
-  Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
   Node* receiverissmi_control = nullptr;
   Node* receiverissmi_effect = effect;
   if (receiverissmi_possible) {
+    Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
     Node* branch = graph()->NewNode(common()->Branch(), check, control);
     control = graph()->NewNode(common()->IfFalse(), branch);
     receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch);
     receiverissmi_effect = effect;
   } else {
-    control = graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
-                               effect, control);
+    receiver = effect = graph()->NewNode(simplified()->CheckTaggedPointer(),
+                                         receiver, effect, control);
   }
 
   // Load the {receiver} map. The resulting effect is the dominating effect for
@@ -159,7 +158,7 @@
     if (receiver_type->Is(Type::String())) {
       Node* check = graph()->NewNode(simplified()->ObjectIsString(), receiver);
       if (j == access_infos.size() - 1) {
-        this_control =
+        this_control = this_effect =
             graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
                              this_effect, fallthrough_control);
         fallthrough_control = nullptr;
@@ -182,10 +181,11 @@
             graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()),
                              receiver_map, jsgraph()->Constant(map));
         if (--num_classes == 0 && j == access_infos.size() - 1) {
-          this_controls.push_back(
+          Node* deoptimize =
               graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
-                               this_effect, fallthrough_control));
-          this_effects.push_back(this_effect);
+                               this_effect, fallthrough_control);
+          this_controls.push_back(deoptimize);
+          this_effects.push_back(deoptimize);
           fallthrough_control = nullptr;
         } else {
           Node* branch =
@@ -237,38 +237,14 @@
       if (access_mode == AccessMode::kStore) {
         Node* check = graph()->NewNode(
             simplified()->ReferenceEqual(Type::Tagged()), value, this_value);
-        this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                        frame_state, this_effect, this_control);
+        this_control = this_effect =
+            graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
+                             this_effect, this_control);
       }
     } else {
       DCHECK(access_info.IsDataField());
       FieldIndex const field_index = access_info.field_index();
-      FieldCheck const field_check = access_info.field_check();
       Type* const field_type = access_info.field_type();
-      switch (field_check) {
-        case FieldCheck::kNone:
-          break;
-        case FieldCheck::kJSArrayBufferViewBufferNotNeutered: {
-          Node* this_buffer = this_effect =
-              graph()->NewNode(simplified()->LoadField(
-                                   AccessBuilder::ForJSArrayBufferViewBuffer()),
-                               this_receiver, this_effect, this_control);
-          Node* this_buffer_bit_field = this_effect =
-              graph()->NewNode(simplified()->LoadField(
-                                   AccessBuilder::ForJSArrayBufferBitField()),
-                               this_buffer, this_effect, this_control);
-          Node* check = graph()->NewNode(
-              machine()->Word32Equal(),
-              graph()->NewNode(machine()->Word32And(), this_buffer_bit_field,
-                               jsgraph()->Int32Constant(
-                                   1 << JSArrayBuffer::WasNeutered::kShift)),
-              jsgraph()->Int32Constant(0));
-          this_control =
-              graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
-                               this_effect, this_control);
-          break;
-        }
-      }
       if (access_mode == AccessMode::kLoad &&
           access_info.holder().ToHandle(&holder)) {
         this_receiver = jsgraph()->Constant(holder);
@@ -284,6 +260,11 @@
           field_type,  MachineType::AnyTagged(), kFullWriteBarrier};
       if (access_mode == AccessMode::kLoad) {
         if (field_type->Is(Type::UntaggedFloat64())) {
+          // TODO(turbofan): We remove the representation axis from the type to
+          // avoid uninhabited representation types. This is a workaround until
+          // the {PropertyAccessInfo} is using {MachineRepresentation} instead.
+          field_access.type = Type::Union(
+              field_type, Type::Representation(Type::Number(), zone()), zone());
           if (!field_index.is_inobject() || field_index.is_hidden_field() ||
               !FLAG_unbox_double_fields) {
             this_storage = this_effect =
@@ -300,9 +281,14 @@
       } else {
         DCHECK_EQ(AccessMode::kStore, access_mode);
         if (field_type->Is(Type::UntaggedFloat64())) {
+          // TODO(turbofan): We remove the representation axis from the type to
+          // avoid uninhabited representation types. This is a workaround until
+          // the {PropertyAccessInfo} is using {MachineRepresentation} instead.
+          field_access.type = Type::Union(
+              field_type, Type::Representation(Type::Number(), zone()), zone());
           Node* check =
               graph()->NewNode(simplified()->ObjectIsNumber(), this_value);
-          this_control =
+          this_control = this_effect =
               graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
                                this_effect, this_control);
           this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()),
@@ -312,8 +298,9 @@
               !FLAG_unbox_double_fields) {
             if (access_info.HasTransitionMap()) {
               // Allocate a MutableHeapNumber for the new property.
-              this_effect =
-                  graph()->NewNode(common()->BeginRegion(), this_effect);
+              this_effect = graph()->NewNode(
+                  common()->BeginRegion(RegionObservability::kNotObservable),
+                  this_effect);
               Node* this_box = this_effect =
                   graph()->NewNode(simplified()->Allocate(NOT_TENURED),
                                    jsgraph()->Constant(HeapNumber::kSize),
@@ -343,19 +330,12 @@
             field_access.machine_type = MachineType::Float64();
           }
         } else if (field_type->Is(Type::TaggedSigned())) {
-          Node* check =
-              graph()->NewNode(simplified()->ObjectIsSmi(), this_value);
-          this_control =
-              graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
+          this_value = this_effect =
+              graph()->NewNode(simplified()->CheckTaggedSigned(), this_value,
                                this_effect, this_control);
-          this_value =
-              graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi),
-                               this_value, this_control);
         } else if (field_type->Is(Type::TaggedPointer())) {
-          Node* check =
-              graph()->NewNode(simplified()->ObjectIsSmi(), this_value);
-          this_control =
-              graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
+          this_value = this_effect =
+              graph()->NewNode(simplified()->CheckTaggedPointer(), this_value,
                                this_effect, this_control);
           if (field_type->NumClasses() == 1) {
             // Emit a map check for the value.
@@ -365,7 +345,7 @@
             Node* check = graph()->NewNode(
                 simplified()->ReferenceEqual(Type::Internal()), this_value_map,
                 jsgraph()->Constant(field_type->Classes().Current()));
-            this_control =
+            this_control = this_effect =
                 graph()->NewNode(common()->DeoptimizeUnless(), check,
                                  frame_state, this_effect, this_control);
           } else {
@@ -376,7 +356,9 @@
         }
         Handle<Map> transition_map;
         if (access_info.transition_map().ToHandle(&transition_map)) {
-          this_effect = graph()->NewNode(common()->BeginRegion(), this_effect);
+          this_effect = graph()->NewNode(
+              common()->BeginRegion(RegionObservability::kObservable),
+              this_effect);
           this_effect = graph()->NewNode(
               simplified()->StoreField(AccessBuilder::ForMap()), this_receiver,
               jsgraph()->Constant(transition_map), this_effect, this_control);
@@ -522,9 +504,9 @@
          node->opcode() == IrOpcode::kJSStoreProperty);
   Node* receiver = NodeProperties::GetValueInput(node, 0);
   Node* context = NodeProperties::GetContextInput(node);
-  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
   Node* effect = NodeProperties::GetEffectInput(node);
   Node* control = NodeProperties::GetControlInput(node);
+  Node* frame_state = NodeProperties::FindFrameStateBefore(node);
 
   // Not much we can do if deoptimization support is disabled.
   if (!(flags() & kDeoptimizationEnabled)) return NoChange();
@@ -555,9 +537,8 @@
   ZoneVector<Node*> controls(zone());
 
   // Ensure that {receiver} is a heap object.
-  Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
-  control = graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
-                             effect, control);
+  receiver = effect = graph()->NewNode(simplified()->CheckTaggedPointer(),
+                                       receiver, effect, control);
 
   // Load the {receiver} map. The resulting effect is the dominating effect for
   // all (polymorphic) branches.
@@ -597,17 +578,19 @@
           // TODO(turbofan): This is ugly as hell! We should probably introduce
           // macro-ish operators for property access that encapsulate this whole
           // mess.
-          this_controls.push_back(graph()->NewNode(common()->DeoptimizeUnless(),
-                                                   check, frame_state, effect,
-                                                   fallthrough_control));
+          Node* deoptimize =
+              graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
+                               effect, fallthrough_control);
+          this_controls.push_back(deoptimize);
+          this_effects.push_back(deoptimize);
           fallthrough_control = nullptr;
         } else {
           Node* branch =
               graph()->NewNode(common()->Branch(), check, fallthrough_control);
           this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+          this_effects.push_back(effect);
           fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
         }
-        this_effects.push_back(effect);
         if (!map->IsJSArrayMap()) receiver_is_jsarray = false;
       }
 
@@ -624,7 +607,7 @@
             simplified()->ReferenceEqual(Type::Any()), receiver_map,
             jsgraph()->HeapConstant(transition_source));
         if (--num_transitions == 0 && j == access_infos.size() - 1) {
-          transition_control =
+          transition_control = transition_effect =
               graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
                                transition_effect, fallthrough_control);
           fallthrough_control = nullptr;
@@ -647,8 +630,7 @@
           // Instance migration, let the stub deal with the {receiver}.
           TransitionElementsKindStub stub(isolate(),
                                           transition_source->elements_kind(),
-                                          transition_target->elements_kind(),
-                                          transition_source->IsJSArrayMap());
+                                          transition_target->elements_kind());
           CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
               isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 0,
               CallDescriptor::kNeedsFrameState, node->op()->properties());
@@ -657,6 +639,7 @@
               receiver, jsgraph()->HeapConstant(transition_target), context,
               frame_state, transition_effect, transition_control);
         }
+
         this_controls.push_back(transition_control);
         this_effects.push_back(transition_effect);
       }
@@ -675,6 +658,14 @@
             graph()->NewNode(common()->EffectPhi(this_control_count),
                              this_control_count + 1, &this_effects.front());
       }
+
+      // TODO(turbofan): The effect/control linearization will not find a
+      // FrameState after the StoreField or Call that is generated for the
+      // elements kind transition above. This is because those operators
+      // don't have the kNoWrite flag on it, even though they are not
+      // observable by JavaScript.
+      this_effect = graph()->NewNode(common()->Checkpoint(), frame_state,
+                                     this_effect, this_control);
     }
 
     // Certain stores need a prototype chain check because shape changes
@@ -685,28 +676,6 @@
       AssumePrototypesStable(receiver_type, native_context, holder);
     }
 
-    // Check that the {index} is actually a Number.
-    if (!NumberMatcher(this_index).HasValue()) {
-      Node* check =
-          graph()->NewNode(simplified()->ObjectIsNumber(), this_index);
-      this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                      frame_state, this_effect, this_control);
-      this_index = graph()->NewNode(simplified()->TypeGuard(Type::Number()),
-                                    this_index, this_control);
-    }
-
-    // Convert the {index} to an unsigned32 value and check if the result is
-    // equal to the original {index}.
-    if (!NumberMatcher(this_index).IsInRange(0.0, kMaxUInt32)) {
-      Node* this_index32 =
-          graph()->NewNode(simplified()->NumberToUint32(), this_index);
-      Node* check = graph()->NewNode(simplified()->NumberEqual(), this_index32,
-                                     this_index);
-      this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                      frame_state, this_effect, this_control);
-      this_index = this_index32;
-    }
-
     // TODO(bmeurer): We currently specialize based on elements kind. We should
     // also be able to properly support strings and other JSObjects here.
     ElementsKind elements_kind = access_info.elements_kind();
@@ -725,8 +694,9 @@
       Node* check = graph()->NewNode(
           simplified()->ReferenceEqual(Type::Any()), this_elements_map,
           jsgraph()->HeapConstant(factory()->fixed_array_map()));
-      this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                      frame_state, this_effect, this_control);
+      this_control = this_effect =
+          graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
+                           this_effect, this_control);
     }
 
     // Load the length of the {receiver}.
@@ -741,10 +711,9 @@
                   this_elements, this_effect, this_control);
 
     // Check that the {index} is in the valid range for the {receiver}.
-    Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index,
-                                   this_length);
-    this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                    frame_state, this_effect, this_control);
+    this_index = this_effect =
+        graph()->NewNode(simplified()->CheckBounds(), this_index, this_length,
+                         this_effect, this_control);
 
     // Compute the element access.
     Type* element_type = Type::Any();
@@ -781,45 +750,26 @@
       if (elements_kind == FAST_HOLEY_ELEMENTS ||
           elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
         // Perform the hole check on the result.
-        Node* check =
-            graph()->NewNode(simplified()->ReferenceEqual(element_access.type),
-                             this_value, jsgraph()->TheHoleConstant());
+        CheckTaggedHoleMode mode = CheckTaggedHoleMode::kNeverReturnHole;
         // Check if we are allowed to turn the hole into undefined.
         Type* initial_holey_array_type = Type::Class(
             handle(isolate()->get_initial_js_array_map(elements_kind)),
             graph()->zone());
         if (receiver_type->NowIs(initial_holey_array_type) &&
             isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
-          Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
-                                          check, this_control);
-          Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-          Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
           // Add a code dependency on the array protector cell.
           AssumePrototypesStable(receiver_type, native_context,
                                  isolate()->initial_object_prototype());
           dependencies()->AssumePropertyCell(factory()->array_protector());
           // Turn the hole into undefined.
-          this_control =
-              graph()->NewNode(common()->Merge(2), if_true, if_false);
-          this_value = graph()->NewNode(
-              common()->Phi(MachineRepresentation::kTagged, 2),
-              jsgraph()->UndefinedConstant(), this_value, this_control);
-          element_type =
-              Type::Union(element_type, Type::Undefined(), graph()->zone());
-        } else {
-          // Deoptimize in case of the hole.
-          this_control =
-              graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
-                               this_effect, this_control);
+          mode = CheckTaggedHoleMode::kConvertHoleToUndefined;
         }
-        // Rename the result to represent the actual type (not polluted by the
-        // hole).
-        this_value = graph()->NewNode(simplified()->TypeGuard(element_type),
-                                      this_value, this_control);
+        this_value = this_effect =
+            graph()->NewNode(simplified()->CheckTaggedHole(mode), this_value,
+                             this_effect, this_control);
       } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
         // Perform the hole check on the result.
-        Node* check =
-            graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value);
+        CheckFloat64HoleMode mode = CheckFloat64HoleMode::kNeverReturnHole;
         // Check if we are allowed to return the hole directly.
         Type* initial_holey_array_type = Type::Class(
             handle(isolate()->get_initial_js_array_map(elements_kind)),
@@ -830,33 +780,32 @@
           AssumePrototypesStable(receiver_type, native_context,
                                  isolate()->initial_object_prototype());
           dependencies()->AssumePropertyCell(factory()->array_protector());
-          // Turn the hole into undefined.
-          this_value = graph()->NewNode(
-              common()->Select(MachineRepresentation::kTagged,
-                               BranchHint::kFalse),
-              check, jsgraph()->UndefinedConstant(), this_value);
-        } else {
-          // Deoptimize in case of the hole.
-          this_control =
-              graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
-                               this_effect, this_control);
+          // Return the signaling NaN hole directly if all uses are truncating.
+          mode = CheckFloat64HoleMode::kAllowReturnHole;
         }
+        this_value = this_effect =
+            graph()->NewNode(simplified()->CheckFloat64Hole(mode), this_value,
+                             this_effect, this_control);
       }
     } else {
       DCHECK_EQ(AccessMode::kStore, access_mode);
       if (IsFastSmiElementsKind(elements_kind)) {
-        Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value);
-        this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                        frame_state, this_effect, this_control);
-        this_value = graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi),
-                                      this_value, this_control);
+        this_value = this_effect =
+            graph()->NewNode(simplified()->CheckTaggedSigned(), this_value,
+                             this_effect, this_control);
       } else if (IsFastDoubleElementsKind(elements_kind)) {
         Node* check =
             graph()->NewNode(simplified()->ObjectIsNumber(), this_value);
-        this_control = graph()->NewNode(common()->DeoptimizeUnless(), check,
-                                        frame_state, this_effect, this_control);
+        this_control = this_effect =
+            graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
+                             this_effect, this_control);
         this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()),
                                       this_value, this_control);
+        // Make sure we do not store signalling NaNs into holey double arrays.
+        if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
+          this_value =
+              graph()->NewNode(simplified()->NumberSilenceNaN(), this_value);
+        }
       }
       this_effect = graph()->NewNode(simplified()->StoreElement(element_access),
                                      this_elements, this_index, this_value,
@@ -960,9 +909,9 @@
 
 
 Reduction JSNativeContextSpecialization::ReduceSoftDeoptimize(Node* node) {
-  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
   Node* effect = NodeProperties::GetEffectInput(node);
   Node* control = NodeProperties::GetControlInput(node);
+  Node* frame_state = NodeProperties::FindFrameStateBefore(node);
   Node* deoptimize =
       graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kSoft), frame_state,
                        effect, control);