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/frames.cc b/src/frames.cc
index 0ba8ea0..d60ab29 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -6,23 +6,20 @@
 
 #include <sstream>
 
-#include "src/v8.h"
-
-#include "src/ast.h"
+#include "src/ast/ast.h"
+#include "src/ast/scopeinfo.h"
 #include "src/base/bits.h"
 #include "src/deoptimizer.h"
 #include "src/frames-inl.h"
-#include "src/full-codegen.h"
-#include "src/heap/mark-compact.h"
+#include "src/full-codegen/full-codegen.h"
+#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
-#include "src/scopeinfo.h"
 #include "src/string-stream.h"
 #include "src/vm-state-inl.h"
 
 namespace v8 {
 namespace internal {
 
-
 ReturnAddressLocationResolver
     StackFrame::return_address_location_resolver_ = NULL;
 
@@ -188,7 +185,7 @@
     Object* script = frame()->function()->shared()->script();
     // Don't show functions from native scripts to user.
     return (script->IsScript() &&
-            Script::TYPE_NATIVE != Script::cast(script)->type()->value());
+            Script::TYPE_NATIVE != Script::cast(script)->type());
 }
 
 
@@ -321,9 +318,6 @@
   if (!IsValidStackAddress(sp)) return false;
   StackFrame::State state;
   ExitFrame::FillState(fp, sp, &state);
-  if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) {
-    return false;
-  }
   return *state.pc_address != NULL;
 }
 
@@ -340,11 +334,8 @@
       // ExternalCallbackScope, just skip them as we cannot collect any useful
       // information about them.
       if (external_callback_scope_->scope_address() < frame_->fp()) {
-        Address* callback_address =
-            external_callback_scope_->callback_address();
-        if (*callback_address != NULL) {
-          frame_->state_.pc_address = callback_address;
-        }
+        frame_->state_.pc_address =
+            external_callback_scope_->callback_entrypoint_address();
         external_callback_scope_ = external_callback_scope_->previous();
         DCHECK(external_callback_scope_ == NULL ||
                external_callback_scope_->scope_address() > frame_->fp());
@@ -380,20 +371,13 @@
 }
 
 
-bool StackFrame::HasHandler() const {
-  StackHandlerIterator it(this, top_handler());
-  return !it.done();
-}
-
-
 #ifdef DEBUG
 static bool GcSafeCodeContains(HeapObject* object, Address addr);
 #endif
 
 
-void StackFrame::IteratePc(ObjectVisitor* v,
-                           Address* pc_address,
-                           Code* holder) {
+void StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address,
+                           Address* constant_pool_address, Code* holder) {
   Address pc = *pc_address;
   DCHECK(GcSafeCodeContains(holder, pc));
   unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
@@ -403,6 +387,9 @@
     holder = reinterpret_cast<Code*>(code);
     pc = holder->instruction_start() + pc_offset;
     *pc_address = pc;
+    if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
+      *constant_pool_address = holder->constant_pool();
+    }
   }
 }
 
@@ -417,25 +404,67 @@
 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
                                          State* state) {
   DCHECK(state->fp != NULL);
-  if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
-    return ARGUMENTS_ADAPTOR;
+
+  if (!iterator->can_access_heap_objects_) {
+    // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
+    // means that we are being called from the profiler, which can interrupt
+    // the VM with a signal at any arbitrary instruction, with essentially
+    // anything on the stack. So basically none of these checks are 100%
+    // reliable.
+    if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
+      // An adapter frame has a special SMI constant for the context and
+      // is not distinguished through the marker.
+      return ARGUMENTS_ADAPTOR;
+    }
+    Object* marker =
+        Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
+    if (marker->IsSmi()) {
+      return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
+    } else {
+      return JAVA_SCRIPT;
+    }
   }
-  // The marker and function offsets overlap. If the marker isn't a
-  // smi then the frame is a JavaScript frame -- and the marker is
-  // really the function.
-  const int offset = StandardFrameConstants::kMarkerOffset;
-  Object* marker = Memory::Object_at(state->fp + offset);
-  if (!marker->IsSmi()) {
-    // If we're using a "safe" stack iterator, we treat optimized
-    // frames as normal JavaScript frames to avoid having to look
-    // into the heap to determine the state. This is safe as long
-    // as nobody tries to GC...
-    if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT;
-    Code::Kind kind = GetContainingCode(iterator->isolate(),
-                                        *(state->pc_address))->kind();
-    DCHECK(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
-    return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
+
+  // Look up the code object to figure out the type of the stack frame.
+  Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address));
+
+  Object* marker =
+      Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
+  if (code_obj != nullptr) {
+    switch (code_obj->kind()) {
+      case Code::FUNCTION:
+        return JAVA_SCRIPT;
+      case Code::OPTIMIZED_FUNCTION:
+        return OPTIMIZED;
+      case Code::WASM_FUNCTION:
+        return STUB;
+      case Code::BUILTIN:
+        if (!marker->IsSmi()) {
+          if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
+            // An adapter frame has a special SMI constant for the context and
+            // is not distinguished through the marker.
+            return ARGUMENTS_ADAPTOR;
+          } else {
+            // The interpreter entry trampoline has a non-SMI marker.
+            DCHECK(code_obj->is_interpreter_entry_trampoline());
+            return INTERPRETED;
+          }
+        }
+        break;  // Marker encodes the frame type.
+      case Code::HANDLER:
+        if (!marker->IsSmi()) {
+          // Only hydrogen code stub handlers can have a non-SMI marker.
+          DCHECK(code_obj->is_hydrogen_stub());
+          return OPTIMIZED;
+        }
+        break;  // Marker encodes the frame type.
+      default:
+        break;  // Marker encodes the frame type.
+    }
   }
+
+  // Didn't find a code object, or the code kind wasn't specific enough.
+  // The marker should encode the frame type.
   return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
 }
 
@@ -512,7 +541,7 @@
   state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
   state->pc_address = ResolveReturnAddressLocation(
       reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
-  if (FLAG_enable_ool_constant_pool) {
+  if (FLAG_enable_embedded_constant_pool) {
     state->constant_pool_address = reinterpret_cast<Address*>(
         fp() + ExitFrameConstants::kConstantPoolOffset);
   }
@@ -527,11 +556,8 @@
 void ExitFrame::Iterate(ObjectVisitor* v) const {
   // The arguments are traversed as part of the expression stack of
   // the calling frame.
-  IteratePc(v, pc_address(), LookupCode());
+  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
   v->VisitPointer(&code_slot());
-  if (FLAG_enable_ool_constant_pool) {
-    v->VisitPointer(&constant_pool_slot());
-  }
 }
 
 
@@ -559,8 +585,11 @@
   state->fp = fp;
   state->pc_address = ResolveReturnAddressLocation(
       reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
-  state->constant_pool_address =
-      reinterpret_cast<Address*>(fp + ExitFrameConstants::kConstantPoolOffset);
+  // The constant pool recorded in the exit frame is not associated
+  // with the pc in this state (the return address into a C entry
+  // stub).  ComputeCallerState will retrieve the constant pool
+  // together with the associated caller pc.
+  state->constant_pool_address = NULL;
 }
 
 
@@ -608,15 +637,6 @@
 }
 
 
-bool StandardFrame::IsExpressionInsideHandler(int n) const {
-  Address address = GetExpressionAddress(n);
-  for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
-    if (it.handler()->includes(address)) return true;
-  }
-  return false;
-}
-
-
 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
   // Make sure that we're not doing "safe" stack frame iteration. We cannot
   // possibly find pointers in optimized frames in that state.
@@ -645,7 +665,9 @@
   if (safepoint_entry.has_doubles()) {
     // Number of doubles not known at snapshot time.
     DCHECK(!isolate()->serializer_enabled());
-    parameters_base += DoubleRegister::NumAllocatableRegisters() *
+    parameters_base +=
+        RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT)
+            ->num_allocatable_double_registers() *
         kDoubleSize / kPointerSize;
   }
 
@@ -678,7 +700,7 @@
   }
 
   // Visit the return address in the callee and incoming arguments.
-  IteratePc(v, pc_address(), code);
+  IteratePc(v, pc_address(), constant_pool_address(), code);
 
   // Visit the context in stub frame and JavaScript frame.
   // Visit the function in JavaScript frame.
@@ -710,12 +732,6 @@
 
 
 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
-#ifdef DEBUG
-  // Make sure that optimized frames do not contain any stack handlers.
-  StackHandlerIterator it(this, top_handler());
-  DCHECK(it.done());
-#endif
-
   IterateCompiledFrame(v);
 }
 
@@ -735,9 +751,18 @@
 }
 
 
+bool JavaScriptFrame::HasInlinedFrames() const {
+  List<JSFunction*> functions(1);
+  GetFunctions(&functions);
+  return functions.length() > 1;
+}
+
+
 int JavaScriptFrame::GetArgumentsLength() const {
   // If there is an arguments adaptor frame get the arguments length from it.
   if (has_adapted_arguments()) {
+    STATIC_ASSERT(ArgumentsAdaptorFrameConstants::kLengthOffset ==
+                  StandardFrameConstants::kExpressionsOffset);
     return Smi::cast(GetExpression(caller_fp(), 0))->value();
   } else {
     return GetNumberOfIncomingArguments();
@@ -754,7 +779,7 @@
   DCHECK(can_access_heap_objects() &&
          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
 
-  return function()->shared()->formal_parameter_count();
+  return function()->shared()->internal_formal_parameter_count();
 }
 
 
@@ -763,7 +788,7 @@
 }
 
 
-void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) {
+void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const {
   DCHECK(functions->length() == 0);
   functions->Add(function());
 }
@@ -782,6 +807,16 @@
 }
 
 
+int JavaScriptFrame::LookupExceptionHandlerInTable(
+    int* stack_slots, HandlerTable::CatchPrediction* prediction) {
+  Code* code = LookupCode();
+  DCHECK(!code->is_optimized_code());
+  HandlerTable* table = HandlerTable::cast(code->handler_table());
+  int pc_offset = static_cast<int>(pc() - code->entry());
+  return table->LookupRange(pc_offset, stack_slots, prediction);
+}
+
+
 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code,
                                              Address pc, FILE* file,
                                              bool print_line_number) {
@@ -799,7 +834,7 @@
       Object* script_name_raw = script->name();
       if (script_name_raw->IsString()) {
         String* script_name = String::cast(script->name());
-        SmartArrayPointer<char> c_script_name =
+        base::SmartArrayPointer<char> c_script_name =
             script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
         PrintF(file, " at %s:%d", c_script_name.get(), line);
       } else {
@@ -843,72 +878,34 @@
 }
 
 
-void JavaScriptFrame::SaveOperandStack(FixedArray* store,
-                                       int* stack_handler_index) const {
+void JavaScriptFrame::SaveOperandStack(FixedArray* store) const {
   int operands_count = store->length();
   DCHECK_LE(operands_count, ComputeOperandsCount());
-
-  // Visit the stack in LIFO order, saving operands and stack handlers into the
-  // array.  The saved stack handlers store a link to the next stack handler,
-  // which will allow RestoreOperandStack to rewind the handlers.
-  StackHandlerIterator it(this, top_handler());
-  int i = operands_count - 1;
-  *stack_handler_index = -1;
-  for (; !it.done(); it.Advance()) {
-    StackHandler* handler = it.handler();
-    // Save operands pushed after the handler was pushed.
-    for (; GetOperandSlot(i) < handler->address(); i--) {
-      store->set(i, GetOperand(i));
-    }
-    DCHECK_GE(i + 1, StackHandlerConstants::kSlotCount);
-    DCHECK_EQ(handler->address(), GetOperandSlot(i));
-    int next_stack_handler_index = i + 1 - StackHandlerConstants::kSlotCount;
-    handler->Unwind(isolate(), store, next_stack_handler_index,
-                    *stack_handler_index);
-    *stack_handler_index = next_stack_handler_index;
-    i -= StackHandlerConstants::kSlotCount;
-  }
-
-  // Save any remaining operands.
-  for (; i >= 0; i--) {
+  for (int i = 0; i < operands_count; i++) {
     store->set(i, GetOperand(i));
   }
 }
 
 
-void JavaScriptFrame::RestoreOperandStack(FixedArray* store,
-                                          int stack_handler_index) {
+void JavaScriptFrame::RestoreOperandStack(FixedArray* store) {
   int operands_count = store->length();
   DCHECK_LE(operands_count, ComputeOperandsCount());
-  int i = 0;
-  while (i <= stack_handler_index) {
-    if (i < stack_handler_index) {
-      // An operand.
-      DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
-      Memory::Object_at(GetOperandSlot(i)) = store->get(i);
-      i++;
-    } else {
-      // A stack handler.
-      DCHECK_EQ(i, stack_handler_index);
-      // The FixedArray store grows up.  The stack grows down.  So the operand
-      // slot for i actually points to the bottom of the top word in the
-      // handler.  The base of the StackHandler* is the address of the bottom
-      // word, which will be the last slot that is in the handler.
-      int handler_slot_index = i + StackHandlerConstants::kSlotCount - 1;
-      StackHandler *handler =
-          StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
-      stack_handler_index = handler->Rewind(isolate(), store, i, fp());
-      i += StackHandlerConstants::kSlotCount;
-    }
-  }
-
-  for (; i < operands_count; i++) {
+  for (int i = 0; i < operands_count; i++) {
     DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
     Memory::Object_at(GetOperandSlot(i)) = store->get(i);
   }
 }
 
 
+FrameSummary::FrameSummary(Object* receiver, JSFunction* function, Code* code,
+                           int offset, bool is_constructor)
+    : receiver_(receiver, function->GetIsolate()),
+      function_(function),
+      code_(code),
+      offset_(offset),
+      is_constructor_(is_constructor) {}
+
+
 void FrameSummary::Print() {
   PrintF("receiver: ");
   receiver_->ShortPrint();
@@ -922,85 +919,74 @@
 }
 
 
-JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array,
-                                      int literal_id) {
-  if (literal_id == Translation::kSelfLiteralId) {
-    return function();
-  }
-
-  return JSFunction::cast(literal_array->get(literal_id));
-}
-
-
 void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
   DCHECK(frames->length() == 0);
   DCHECK(is_optimized());
 
   // Delegate to JS frame in absence of turbofan deoptimization.
   // TODO(turbofan): Revisit once we support deoptimization across the board.
-  if (LookupCode()->is_turbofanned() && !FLAG_turbo_deoptimization) {
+  if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() &&
+      !FLAG_turbo_asm_deoptimization) {
     return JavaScriptFrame::Summarize(frames);
   }
 
+  DisallowHeapAllocation no_gc;
   int deopt_index = Safepoint::kNoDeoptimizationIndex;
-  DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
-  FixedArray* literal_array = data->LiteralArray();
-
-  // BUG(3243555): Since we don't have a lazy-deopt registered at
-  // throw-statements, we can't use the translation at the call-site of
-  // throw. An entry with no deoptimization index indicates a call-site
-  // without a lazy-deopt. As a consequence we are not allowed to inline
-  // functions containing throw.
-  DCHECK(deopt_index != Safepoint::kNoDeoptimizationIndex);
+  DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
+  FixedArray* const literal_array = data->LiteralArray();
 
   TranslationIterator it(data->TranslationByteArray(),
                          data->TranslationIndex(deopt_index)->value());
-  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
-  DCHECK(opcode == Translation::BEGIN);
+  Translation::Opcode frame_opcode =
+      static_cast<Translation::Opcode>(it.Next());
+  DCHECK_EQ(Translation::BEGIN, frame_opcode);
   it.Next();  // Drop frame count.
   int jsframe_count = it.Next();
 
   // We create the summary in reverse order because the frames
   // in the deoptimization translation are ordered bottom-to-top.
   bool is_constructor = IsConstructor();
-  int i = jsframe_count;
-  while (i > 0) {
-    opcode = static_cast<Translation::Opcode>(it.Next());
-    if (opcode == Translation::JS_FRAME) {
-      i--;
-      BailoutId ast_id = BailoutId(it.Next());
-      JSFunction* function = LiteralAt(literal_array, it.Next());
+  while (jsframe_count != 0) {
+    frame_opcode = static_cast<Translation::Opcode>(it.Next());
+    if (frame_opcode == Translation::JS_FRAME ||
+        frame_opcode == Translation::INTERPRETED_FRAME) {
+      jsframe_count--;
+      BailoutId const ast_id = BailoutId(it.Next());
+      SharedFunctionInfo* const shared_info =
+          SharedFunctionInfo::cast(literal_array->get(it.Next()));
       it.Next();  // Skip height.
 
-      // The translation commands are ordered and the receiver is always
-      // at the first position.
+      // The translation commands are ordered and the function is always
+      // at the first position, and the receiver is next.
+      Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
+
+      // Get the correct function in the optimized frame.
+      JSFunction* function;
+      if (opcode == Translation::LITERAL) {
+        function = JSFunction::cast(literal_array->get(it.Next()));
+      } else if (opcode == Translation::STACK_SLOT) {
+        function = JSFunction::cast(StackSlotAt(it.Next()));
+      } else {
+        CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode);
+        function = this->function();
+      }
+      DCHECK_EQ(shared_info, function->shared());
+
       // If we are at a call, the receiver is always in a stack slot.
       // Otherwise we are not guaranteed to get the receiver value.
       opcode = static_cast<Translation::Opcode>(it.Next());
-      int index = it.Next();
 
       // Get the correct receiver in the optimized frame.
-      Object* receiver = NULL;
+      Object* receiver;
       if (opcode == Translation::LITERAL) {
-        receiver = data->LiteralArray()->get(index);
+        receiver = literal_array->get(it.Next());
       } else if (opcode == Translation::STACK_SLOT) {
-        // Positive index means the value is spilled to the locals
-        // area. Negative means it is stored in the incoming parameter
-        // area.
-        if (index >= 0) {
-          receiver = GetExpression(index);
-        } else {
-          // Index -1 overlaps with last parameter, -n with the first parameter,
-          // (-n - 1) with the receiver with n being the number of parameters
-          // of the outermost, optimized frame.
-          int parameter_count = ComputeParametersCount();
-          int parameter_index = index + parameter_count;
-          receiver = (parameter_index == -1)
-              ? this->receiver()
-              : this->GetParameter(parameter_index);
-        }
+        receiver = StackSlotAt(it.Next());
+      } else if (opcode == Translation::JS_FRAME_FUNCTION) {
+        receiver = this->function();
       } else {
         // The receiver is not in a stack slot nor in a literal.  We give up.
+        it.Skip(Translation::NumberOfOperandsFor(opcode));
         // TODO(3029): Materializing a captured object (or duplicated
         // object) is hard, we return undefined for now. This breaks the
         // produced stack trace, as constructor frames aren't marked as
@@ -1008,35 +994,53 @@
         receiver = isolate()->heap()->undefined_value();
       }
 
-      Code* code = function->shared()->code();
-      DeoptimizationOutputData* output_data =
-          DeoptimizationOutputData::cast(code->deoptimization_data());
-      unsigned entry = Deoptimizer::GetOutputInfo(output_data,
-                                                  ast_id,
-                                                  function->shared());
-      unsigned pc_offset =
-          FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize;
-      DCHECK(pc_offset > 0);
+      Code* const code = shared_info->code();
 
+      unsigned pc_offset;
+      if (frame_opcode == Translation::JS_FRAME) {
+        DeoptimizationOutputData* const output_data =
+            DeoptimizationOutputData::cast(code->deoptimization_data());
+        unsigned const entry =
+            Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info);
+        pc_offset =
+            FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize;
+        DCHECK_NE(0U, pc_offset);
+      } else {
+        // TODO(rmcilroy): Modify FrameSummary to enable us to summarize
+        // based on the BytecodeArray and bytecode offset.
+        DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME);
+        pc_offset = 0;
+      }
       FrameSummary summary(receiver, function, code, pc_offset, is_constructor);
       frames->Add(summary);
       is_constructor = false;
-    } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) {
+    } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) {
       // The next encountered JS_FRAME will be marked as a constructor call.
-      it.Skip(Translation::NumberOfOperandsFor(opcode));
+      it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
       DCHECK(!is_constructor);
       is_constructor = true;
     } else {
       // Skip over operands to advance to the next opcode.
-      it.Skip(Translation::NumberOfOperandsFor(opcode));
+      it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
     }
   }
   DCHECK(!is_constructor);
 }
 
 
+int OptimizedFrame::LookupExceptionHandlerInTable(
+    int* stack_slots, HandlerTable::CatchPrediction* prediction) {
+  Code* code = LookupCode();
+  DCHECK(code->is_optimized_code());
+  HandlerTable* table = HandlerTable::cast(code->handler_table());
+  int pc_offset = static_cast<int>(pc() - code->entry());
+  *stack_slots = code->stack_slots();
+  return table->LookupReturn(pc_offset, prediction);
+}
+
+
 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
-    int* deopt_index) {
+    int* deopt_index) const {
   DCHECK(is_optimized());
 
   JSFunction* opt_function = function();
@@ -1060,68 +1064,70 @@
 }
 
 
-int OptimizedFrame::GetInlineCount() {
-  DCHECK(is_optimized());
-
-  // Delegate to JS frame in absence of turbofan deoptimization.
-  // TODO(turbofan): Revisit once we support deoptimization across the board.
-  if (LookupCode()->is_turbofanned() && !FLAG_turbo_deoptimization) {
-    return JavaScriptFrame::GetInlineCount();
-  }
-
-  int deopt_index = Safepoint::kNoDeoptimizationIndex;
-  DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
-
-  TranslationIterator it(data->TranslationByteArray(),
-                         data->TranslationIndex(deopt_index)->value());
-  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
-  DCHECK(opcode == Translation::BEGIN);
-  USE(opcode);
-  it.Next();  // Drop frame count.
-  int jsframe_count = it.Next();
-  return jsframe_count;
-}
-
-
-void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
+void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) const {
   DCHECK(functions->length() == 0);
   DCHECK(is_optimized());
 
   // Delegate to JS frame in absence of turbofan deoptimization.
   // TODO(turbofan): Revisit once we support deoptimization across the board.
-  if (LookupCode()->is_turbofanned() && !FLAG_turbo_deoptimization) {
+  if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() &&
+      !FLAG_turbo_asm_deoptimization) {
     return JavaScriptFrame::GetFunctions(functions);
   }
 
+  DisallowHeapAllocation no_gc;
   int deopt_index = Safepoint::kNoDeoptimizationIndex;
-  DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
-  FixedArray* literal_array = data->LiteralArray();
+  DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
+  FixedArray* const literal_array = data->LiteralArray();
 
   TranslationIterator it(data->TranslationByteArray(),
                          data->TranslationIndex(deopt_index)->value());
   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
-  DCHECK(opcode == Translation::BEGIN);
-  it.Next();  // Drop frame count.
+  DCHECK_EQ(Translation::BEGIN, opcode);
+  it.Next();  // Skip frame count.
   int jsframe_count = it.Next();
 
   // We insert the frames in reverse order because the frames
   // in the deoptimization translation are ordered bottom-to-top.
-  while (jsframe_count > 0) {
+  while (jsframe_count != 0) {
     opcode = static_cast<Translation::Opcode>(it.Next());
-    if (opcode == Translation::JS_FRAME) {
+    // Skip over operands to advance to the next opcode.
+    it.Skip(Translation::NumberOfOperandsFor(opcode));
+    if (opcode == Translation::JS_FRAME ||
+        opcode == Translation::INTERPRETED_FRAME) {
       jsframe_count--;
-      it.Next();  // Skip ast id.
-      JSFunction* function = LiteralAt(literal_array, it.Next());
-      it.Next();  // Skip height.
-      functions->Add(function);
-    } else {
-      // Skip over operands to advance to the next opcode.
-      it.Skip(Translation::NumberOfOperandsFor(opcode));
+
+      // The translation commands are ordered and the function is always at the
+      // first position.
+      opcode = static_cast<Translation::Opcode>(it.Next());
+
+      // Get the correct function in the optimized frame.
+      Object* function;
+      if (opcode == Translation::LITERAL) {
+        function = literal_array->get(it.Next());
+      } else if (opcode == Translation::STACK_SLOT) {
+        function = StackSlotAt(it.Next());
+      } else {
+        CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode);
+        function = this->function();
+      }
+      functions->Add(JSFunction::cast(function));
     }
   }
 }
 
 
+int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
+  return StandardFrameConstants::kCallerSPOffset -
+         ((slot_index + 1) * kPointerSize);
+}
+
+
+Object* OptimizedFrame::StackSlotAt(int index) const {
+  return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
+}
+
+
 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
   return Smi::cast(GetExpression(0))->value();
 }
@@ -1160,6 +1166,24 @@
 }
 
 
+namespace {
+
+
+void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
+                         Code* code) {
+  if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
+    std::ostringstream os;
+    os << "--------- s o u r c e   c o d e ---------\n"
+       << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
+       << "\n-----------------------------------------\n";
+    accumulator->Add(os.str().c_str());
+  }
+}
+
+
+}  // namespace
+
+
 void JavaScriptFrame::Print(StringStream* accumulator,
                             PrintMode mode,
                             int index) const {
@@ -1197,7 +1221,7 @@
       accumulator->Add(":~%d", line);
     }
 
-    accumulator->Add("] ");
+    accumulator->Add("] [pc=%p] ", pc);
   }
 
   accumulator->Add("(this=%o", receiver);
@@ -1222,7 +1246,9 @@
     return;
   }
   if (is_optimized()) {
-    accumulator->Add(" {\n// optimized frame\n}\n");
+    accumulator->Add(" {\n// optimized frame\n");
+    PrintFunctionSource(accumulator, shared, code);
+    accumulator->Add("}\n");
     return;
   }
   accumulator->Add(" {\n");
@@ -1286,19 +1312,10 @@
     accumulator->Add("  // expression stack (top to bottom)\n");
   }
   for (int i = expressions_count - 1; i >= expressions_start; i--) {
-    if (IsExpressionInsideHandler(i)) continue;
     accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
   }
 
-  // Print details about the function.
-  if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
-    std::ostringstream os;
-    SharedFunctionInfo* shared = function->shared();
-    os << "--------- s o u r c e   c o d e ---------\n"
-       << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
-       << "\n-----------------------------------------\n";
-    accumulator->Add(os.str().c_str());
-  }
+  PrintFunctionSource(accumulator, shared, code);
 
   accumulator->Add("}\n\n");
 }
@@ -1310,7 +1327,7 @@
   int actual = ComputeParametersCount();
   int expected = -1;
   JSFunction* function = this->function();
-  expected = function->shared()->formal_parameter_count();
+  expected = function->shared()->internal_formal_parameter_count();
 
   PrintIndex(accumulator, mode, index);
   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
@@ -1335,18 +1352,7 @@
 
 
 void EntryFrame::Iterate(ObjectVisitor* v) const {
-  StackHandlerIterator it(this, top_handler());
-  DCHECK(!it.done());
-  StackHandler* handler = it.handler();
-  DCHECK(handler->is_js_entry());
-  handler->Iterate(v, LookupCode());
-#ifdef DEBUG
-  // Make sure that the entry frame does not contain more than one
-  // stack handler.
-  it.Advance();
-  DCHECK(it.done());
-#endif
-  IteratePc(v, pc_address(), LookupCode());
+  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
 }
 
 
@@ -1354,24 +1360,13 @@
   const int offset = StandardFrameConstants::kLastObjectOffset;
   Object** base = &Memory::Object_at(sp());
   Object** limit = &Memory::Object_at(fp() + offset) + 1;
-  for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
-    StackHandler* handler = it.handler();
-    // Traverse pointers down to - but not including - the next
-    // handler in the handler chain. Update the base to skip the
-    // handler and allow the handler to traverse its own pointers.
-    const Address address = handler->address();
-    v->VisitPointers(base, reinterpret_cast<Object**>(address));
-    base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
-    // Traverse the pointers in the handler itself.
-    handler->Iterate(v, LookupCode());
-  }
   v->VisitPointers(base, limit);
 }
 
 
 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
   IterateExpressions(v);
-  IteratePc(v, pc_address(), LookupCode());
+  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
 }
 
 
@@ -1379,7 +1374,7 @@
   // Internal frames only have object pointers on the expression stack
   // as they never have any arguments.
   IterateExpressions(v);
-  IteratePc(v, pc_address(), LookupCode());
+  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
 }
 
 
@@ -1392,7 +1387,7 @@
   const int offset = StandardFrameConstants::kLastObjectOffset;
   limit = &Memory::Object_at(fp() + offset) + 1;
   v->VisitPointers(base, limit);
-  IteratePc(v, pc_address(), LookupCode());
+  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
 }
 
 
@@ -1472,6 +1467,11 @@
 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
     Address inner_pointer) {
   Heap* heap = isolate_->heap();
+  if (!heap->code_space()->Contains(inner_pointer) &&
+      !heap->lo_space()->Contains(inner_pointer)) {
+    return nullptr;
+  }
+
   // Check if the inner pointer points into a large object chunk.
   LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
   if (large_page != NULL) {
@@ -1482,6 +1482,9 @@
   // after the inner pointer.
   Page* page = Page::FromAddress(inner_pointer);
 
+  DCHECK_EQ(page->owner(), heap->code_space());
+  heap->mark_compact_collector()->SweepOrWaitUntilSweepingCompleted(page);
+
   Address addr = page->skip_list()->StartFor(inner_pointer);
 
   Address top = heap->code_space()->top();
@@ -1506,9 +1509,8 @@
     InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
   isolate_->counters()->pc_to_code()->Increment();
   DCHECK(base::bits::IsPowerOfTwo32(kInnerPointerToCodeCacheSize));
-  uint32_t hash = ComputeIntegerHash(
-      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
-      v8::internal::kZeroHashSeed);
+  uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer),
+                                     v8::internal::kZeroHashSeed);
   uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
   InnerPointerToCodeCacheEntry* entry = cache(index);
   if (entry->inner_pointer == inner_pointer) {
@@ -1530,60 +1532,7 @@
 // -------------------------------------------------------------------------
 
 
-void StackHandler::Unwind(Isolate* isolate,
-                          FixedArray* array,
-                          int offset,
-                          int previous_handler_offset) const {
-  STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5);
-  DCHECK_LE(0, offset);
-  DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
-  // Unwinding a stack handler into an array chains it in the opposite
-  // direction, re-using the "next" slot as a "previous" link, so that stack
-  // handlers can be later re-wound in the correct order.  Decode the "state"
-  // slot into "index" and "kind" and store them separately, using the fp slot.
-  array->set(offset, Smi::FromInt(previous_handler_offset));        // next
-  array->set(offset + 1, *code_address());                          // code
-  array->set(offset + 2, Smi::FromInt(static_cast<int>(index())));  // state
-  array->set(offset + 3, *context_address());                       // context
-  array->set(offset + 4, Smi::FromInt(static_cast<int>(kind())));   // fp
-
-  *isolate->handler_address() = next()->address();
-}
-
-
-int StackHandler::Rewind(Isolate* isolate,
-                         FixedArray* array,
-                         int offset,
-                         Address fp) {
-  STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5);
-  DCHECK_LE(0, offset);
-  DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
-  Smi* prev_handler_offset = Smi::cast(array->get(offset));
-  Code* code = Code::cast(array->get(offset + 1));
-  Smi* smi_index = Smi::cast(array->get(offset + 2));
-  Object* context = array->get(offset + 3);
-  Smi* smi_kind = Smi::cast(array->get(offset + 4));
-
-  unsigned state = KindField::encode(static_cast<Kind>(smi_kind->value())) |
-      IndexField::encode(static_cast<unsigned>(smi_index->value()));
-
-  Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
-      *isolate->handler_address();
-  Memory::Object_at(address() + StackHandlerConstants::kCodeOffset) = code;
-  Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset) = state;
-  Memory::Object_at(address() + StackHandlerConstants::kContextOffset) =
-      context;
-  SetFp(address() + StackHandlerConstants::kFPOffset, fp);
-
-  *isolate->handler_address() = address();
-
-  return prev_handler_offset->value();
-}
-
-
-// -------------------------------------------------------------------------
-
-int NumRegs(RegList reglist) { return base::bits::CountPopulation32(reglist); }
+int NumRegs(RegList reglist) { return base::bits::CountPopulation(reglist); }
 
 
 struct JSCallerSavedCodeData {
@@ -1645,4 +1594,5 @@
 }
 
 
-} }  // namespace v8::internal
+}  // namespace internal
+}  // namespace v8