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/debug/liveedit.cc b/src/debug/liveedit.cc
index 50d60a1..aa67537 100644
--- a/src/debug/liveedit.cc
+++ b/src/debug/liveedit.cc
@@ -621,11 +621,9 @@
   this->SetSmiValueField(kParentIndexOffset_, parent_index);
 }
 
-
-void FunctionInfoWrapper::SetFunctionCode(Handle<Code> function_code,
+void FunctionInfoWrapper::SetFunctionCode(Handle<AbstractCode> function_code,
                                           Handle<HeapObject> code_scope_info) {
   // CompileForLiveEdit must deliver full-codegen code.
-  DCHECK(function_code->kind() == Code::FUNCTION);
   Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
   this->SetField(kCodeOffset_, code_wrapper);
 
@@ -640,27 +638,25 @@
   this->SetField(kSharedFunctionInfoOffset_, info_holder);
 }
 
-
-Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
+Handle<AbstractCode> FunctionInfoWrapper::GetFunctionCode() {
   Handle<Object> element = this->GetField(kCodeOffset_);
   Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
   Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
-  CHECK(raw_result->IsCode());
-  return Handle<Code>::cast(raw_result);
+  CHECK(raw_result->IsAbstractCode());
+  return Handle<AbstractCode>::cast(raw_result);
 }
 
-
-MaybeHandle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
+MaybeHandle<TypeFeedbackMetadata> FunctionInfoWrapper::GetFeedbackMetadata() {
   Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
   if (element->IsJSValue()) {
     Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
     Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
     Handle<SharedFunctionInfo> shared =
         Handle<SharedFunctionInfo>::cast(raw_result);
-    return Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
+    return Handle<TypeFeedbackMetadata>(shared->feedback_metadata(), isolate());
   } else {
     // Scripts may never have a SharedFunctionInfo created.
-    return MaybeHandle<TypeFeedbackVector>();
+    return MaybeHandle<TypeFeedbackMetadata>();
   }
 }
 
@@ -863,11 +859,11 @@
  public:
   static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper,
                             Handle<SharedFunctionInfo> shared_info,
-                            Isolate* isolate) {
+                            bool feedback_metadata_changed, Isolate* isolate) {
     int new_literal_count = compile_info_wrapper->GetLiteralCount();
     int old_literal_count = shared_info->num_literals();
 
-    if (old_literal_count == new_literal_count) {
+    if (old_literal_count == new_literal_count && !feedback_metadata_changed) {
       // If literal count didn't change, simply go over all functions
       // and clear literal arrays.
       ClearValuesVisitor visitor;
@@ -878,10 +874,13 @@
       // collect all functions and fix their literal arrays.
       Handle<FixedArray> function_instances =
           CollectJSFunctions(shared_info, isolate);
-      Handle<TypeFeedbackVector> vector(shared_info->feedback_vector());
+      Handle<TypeFeedbackMetadata> feedback_metadata(
+          shared_info->feedback_metadata());
 
       for (int i = 0; i < function_instances->length(); i++) {
         Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
+        Handle<TypeFeedbackVector> vector =
+            TypeFeedbackVector::New(isolate, feedback_metadata);
         Handle<LiteralsArray> new_literals =
             LiteralsArray::New(isolate, vector, new_literal_count, TENURED);
         fun->set_literals(*new_literals);
@@ -929,10 +928,10 @@
   class ClearValuesVisitor {
    public:
     void visit(JSFunction* fun) {
-      FixedArray* literals = fun->literals();
-      int len = literals->length();
+      LiteralsArray* literals = fun->literals();
+      int len = literals->literals_count();
       for (int j = 0; j < len; j++) {
-        literals->set_undefined(j);
+        literals->set_literal_undefined(j);
       }
     }
   };
@@ -1007,18 +1006,20 @@
   SharedInfoWrapper shared_info_wrapper(shared_info_array);
 
   Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
+  bool feedback_metadata_changed = false;
 
   if (shared_info->is_compiled()) {
-    Handle<Code> new_code = compile_info_wrapper.GetFunctionCode();
-    Handle<Code> old_code(shared_info->code());
+    Handle<AbstractCode> new_code = compile_info_wrapper.GetFunctionCode();
     if (shared_info->HasBytecodeArray()) {
-      // The old code is interpreted. If we clear the bytecode array, the
-      // interpreter entry trampoline will self-heal and go to compiled code.
+      DCHECK(new_code->IsBytecodeArray());
+      // The old code is interpreted, the new code must be interpreted as well.
       shared_info->ClearBytecodeArray();
-      shared_info->ReplaceCode(*new_code);
+      shared_info->set_bytecode_array(BytecodeArray::cast(*new_code));
     } else {
+      Handle<Code> old_code(shared_info->code());
       DCHECK(old_code->kind() == Code::FUNCTION);
-      ReplaceCodeObject(old_code, new_code);
+      DCHECK(new_code->kind() == AbstractCode::FUNCTION);
+      ReplaceCodeObject(old_code, Handle<Code>::cast(new_code));
     }
     if (shared_info->HasDebugInfo()) {
       // Existing break points will be re-applied. Reset the debug info here.
@@ -1031,10 +1032,14 @@
     }
     shared_info->DisableOptimization(kLiveEdit);
     // Update the type feedback vector, if needed.
-    MaybeHandle<TypeFeedbackVector> feedback_vector =
-        compile_info_wrapper.GetFeedbackVector();
-    if (!feedback_vector.is_null()) {
-      shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
+    MaybeHandle<TypeFeedbackMetadata> feedback_metadata =
+        compile_info_wrapper.GetFeedbackMetadata();
+    if (!feedback_metadata.is_null()) {
+      Handle<TypeFeedbackMetadata> checked_feedback_metadata =
+          feedback_metadata.ToHandleChecked();
+      feedback_metadata_changed = checked_feedback_metadata->DiffersFrom(
+          shared_info->feedback_metadata());
+      shared_info->set_feedback_metadata(*checked_feedback_metadata);
     }
   }
 
@@ -1043,7 +1048,8 @@
   shared_info->set_start_position(start_position);
   shared_info->set_end_position(end_position);
 
-  LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate);
+  LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info,
+                              feedback_metadata_changed, isolate);
 
   DeoptimizeDependentFunctions(*shared_info);
   isolate->compilation_cache()->Remove(shared_info);
@@ -1063,7 +1069,8 @@
                                  Handle<Object> script_handle) {
   Handle<SharedFunctionInfo> shared_info =
       UnwrapSharedFunctionInfoFromJSValue(function_wrapper);
-  CHECK(script_handle->IsScript() || script_handle->IsUndefined());
+  Isolate* isolate = function_wrapper->GetIsolate();
+  CHECK(script_handle->IsScript() || script_handle->IsUndefined(isolate));
   SharedFunctionInfo::SetScript(shared_info, script_handle);
   shared_info->DisableOptimization(kLiveEdit);
 
@@ -1219,18 +1226,13 @@
   }
 
   Vector<byte> buffer = buffer_writer.GetResult();
+  Handle<ByteArray> reloc_info =
+      isolate->factory()->NewByteArray(buffer.length(), TENURED);
 
-  if (buffer.length() == code->relocation_size()) {
-    // Simply patch relocation area of code.
-    MemCopy(code->relocation_start(), buffer.start(), buffer.length());
-    return code;
-  } else {
-    // Relocation info section now has different size. We cannot simply
-    // rewrite it inside code object. Instead we have to create a new
-    // code object.
-    Handle<Code> result(isolate->factory()->CopyCode(code, buffer));
-    return result;
-  }
+  DisallowHeapAllocation no_gc;
+  code->set_relocation_info(*reloc_info);
+  CopyBytes(code->relocation_start(), buffer.start(), buffer.length());
+  return code;
 }
 
 void PatchPositionsInBytecodeArray(Handle<BytecodeArray> bytecode,
@@ -1248,7 +1250,8 @@
                         iterator.is_statement());
   }
 
-  bytecode->set_source_position_table(*builder.ToSourcePositionTable());
+  Handle<ByteArray> source_position_table = builder.ToSourcePositionTable();
+  bytecode->set_source_position_table(*source_position_table);
 }
 }  // namespace
 
@@ -1601,7 +1604,7 @@
       Handle<Object> new_element =
           JSReceiver::GetElement(isolate, new_shared_array_, i)
               .ToHandleChecked();
-      if (new_element->IsUndefined()) return false;
+      if (new_element->IsUndefined(isolate)) return false;
       Handle<SharedFunctionInfo> new_shared =
           UnwrapSharedFunctionInfoFromJSValue(
               Handle<JSValue>::cast(new_element));
@@ -1619,6 +1622,21 @@
     return false;
   }
 
+  void set_status(LiveEdit::FunctionPatchabilityStatus status) {
+    Isolate* isolate = old_shared_array_->GetIsolate();
+    int len = GetArrayLength(old_shared_array_);
+    for (int i = 0; i < len; ++i) {
+      Handle<Object> old_element =
+          JSReceiver::GetElement(isolate, result_, i).ToHandleChecked();
+      if (!old_element->IsSmi() ||
+          Smi::cast(*old_element)->value() ==
+              LiveEdit::FUNCTION_AVAILABLE_FOR_PATCH) {
+        SetElementSloppy(result_, i,
+                         Handle<Smi>(Smi::FromInt(status), isolate));
+      }
+    }
+  }
+
  private:
   Handle<JSArray> old_shared_array_;
   Handle<JSArray> new_shared_array_;
@@ -1672,7 +1690,7 @@
     if (frame->is_java_script()) {
       SharedFunctionInfo* shared =
           JavaScriptFrame::cast(frame)->function()->shared();
-      if (shared->is_generator()) {
+      if (shared->is_resumable()) {
         non_droppable_frame_found = true;
         non_droppable_reason = LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR;
         break;
@@ -1696,6 +1714,13 @@
           // Fail.
           return NULL;
         }
+        if (non_droppable_reason ==
+                LiveEdit::FUNCTION_BLOCKED_UNDER_GENERATOR &&
+            !target_frame_found) {
+          // Fail.
+          target.set_status(non_droppable_reason);
+          return NULL;
+        }
       }
     }
   }
@@ -1993,7 +2018,7 @@
   FunctionInfoWrapper info = FunctionInfoWrapper::cast(
       *JSReceiver::GetElement(isolate_, result_, current_parent_index_)
            .ToHandleChecked());
-  info.SetFunctionCode(Handle<Code>(shared->code()),
+  info.SetFunctionCode(Handle<AbstractCode>(shared->abstract_code()),
                        Handle<HeapObject>(shared->scope_info()));
   info.SetSharedFunctionInfo(shared);