Reviewers: jarin,

Description:
[turbofan] Record SharedFunctionInfo of inlined functions.

We need the shared function info of inlined functions to prevent code
flushing for their unoptimized code, and also to make sure that liveedit
can find the proper functions to deoptimize.

[email protected]

Please review this at https://codereview.chromium.org/1156403002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+61, -16 lines):
  M src/compiler/ast-graph-builder.cc
  M src/compiler/code-generator.h
  M src/compiler/code-generator.cc
  M src/compiler/common-operator.h
  M src/compiler/common-operator.cc
  M src/compiler/frame-states.h
  M src/compiler/frame-states.cc
  M src/compiler/instruction.h
  M src/compiler/instruction.cc
  M src/compiler/instruction-selector.cc
  M src/objects.cc


Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 038d2beb1e6472e9b01cf843993ca1b592e7dfd1..aaef0569e7b7e172d1a16e0fbcc45c3e322cd5bc 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -851,7 +851,8 @@ Node* AstGraphBuilder::Environment::Checkpoint(
   UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
                     stack_height());

-  const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine);
+  const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine,
+ builder()->info()->shared_info());

   Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
stack_node_, builder()->current_context(),
Index: src/compiler/code-generator.cc
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc
index 16bf92c3639a45c8f9593dfe5affcfd58d0cbd4c..fd7b061e2c87d4cec09495b22b5610dce14b8771 100644
--- a/src/compiler/code-generator.cc
+++ b/src/compiler/code-generator.cc
@@ -45,6 +45,7 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
       handlers_(code->zone()),
       deoptimization_states_(code->zone()),
       deoptimization_literals_(code->zone()),
+      inlined_function_count_(0),
       translations_(code->zone()),
       last_lazy_deopt_pc_(0),
       jump_tables_(nullptr),
@@ -73,6 +74,17 @@ Handle<Code> CodeGenerator::GenerateCode() {
   info->set_prologue_offset(masm()->pc_offset());
   AssemblePrologue();

+  // Define deoptimization literals for all inlined functions.
+  DCHECK_EQ(0u, deoptimization_literals_.size());
+  for (auto frame_state_descriptor : code()->frame_state_descriptors()) {
+    Handle<SharedFunctionInfo> shared_info;
+    if (frame_state_descriptor->shared_info().ToHandle(&shared_info) &&
+        !shared_info.is_identical_to(info->shared_info())) {
+      DefineDeoptimizationLiteral(shared_info);
+    }
+  }
+  inlined_function_count_ = deoptimization_literals_.size();
+
   // Assemble all non-deferred blocks, followed by deferred ones.
   for (int deferred = 0; deferred < 2; ++deferred) {
     for (auto const block : code()->instruction_blocks()) {
@@ -302,7 +314,8 @@ void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
       translations_.CreateByteArray(isolate()->factory());

   data->SetTranslationByteArray(*translation_array);
-  data->SetInlinedFunctionCount(Smi::FromInt(0));
+  data->SetInlinedFunctionCount(
+      Smi::FromInt(static_cast<int>(inlined_function_count_)));
   data->SetOptimizationId(Smi::FromInt(info->optimization_id()));
   // TODO(jarin) The following code was copied over from Lithium, not sure
   // whether the scope or the IsOptimizing condition are really needed.
Index: src/compiler/code-generator.h
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index 206da7041c07839b6e346a7ee6567fa7fe7d58c8..a8df2c3d0b9f4ec53f7c579f80506548a5e4dc27 100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -179,6 +179,7 @@ class CodeGenerator final : public GapResolver::Assembler {
   ZoneVector<HandlerInfo> handlers_;
   ZoneDeque<DeoptimizationState*> deoptimization_states_;
   ZoneDeque<Handle<Object>> deoptimization_literals_;
+  size_t inlined_function_count_;
   TranslationBuffer translations_;
   int last_lazy_deopt_pc_;
   JumpTable* jump_tables_;
Index: src/compiler/common-operator.cc
diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc index 874ad29cef7d9efa7129fcd92e55333755159a1a..330eeec7d95f3ea386283066713b3b3f8dd8ef1c 100644
--- a/src/compiler/common-operator.cc
+++ b/src/compiler/common-operator.cc
@@ -651,12 +651,14 @@ const Operator* CommonOperatorBuilder::TypedStateValues(

 const Operator* CommonOperatorBuilder::FrameState(
     FrameStateType type, BailoutId bailout_id,
-    OutputFrameStateCombine state_combine) {
-  return new (zone()) Operator1<FrameStateCallInfo>(         // --
-      IrOpcode::kFrameState, Operator::kPure,                // opcode
-      "FrameState",                                          // name
-      5, 0, 0, 1, 0, 0,                                      // counts
-      FrameStateCallInfo(type, bailout_id, state_combine));  // parameter
+    OutputFrameStateCombine state_combine,
+    MaybeHandle<SharedFunctionInfo> shared_info) {
+ FrameStateCallInfo state_info(type, bailout_id, state_combine, shared_info);
+  return new (zone()) Operator1<FrameStateCallInfo>(  // --
+      IrOpcode::kFrameState, Operator::kPure,         // opcode
+      "FrameState",                                   // name
+      5, 0, 0, 1, 0, 0,                               // counts
+      state_info);                                    // parameter
 }


Index: src/compiler/common-operator.h
diff --git a/src/compiler/common-operator.h b/src/compiler/common-operator.h
index cc23bf1c8fb040ab449c9022924b4b12264ca09c..1c004448b8a9a19e40f3c46f1ab6c9615323042d 100644
--- a/src/compiler/common-operator.h
+++ b/src/compiler/common-operator.h
@@ -129,7 +129,9 @@ class CommonOperatorBuilder final : public ZoneObject {
   const Operator* StateValues(int arguments);
   const Operator* TypedStateValues(const ZoneVector<MachineType>* types);
   const Operator* FrameState(FrameStateType type, BailoutId bailout_id,
-                             OutputFrameStateCombine state_combine);
+                             OutputFrameStateCombine state_combine,
+                             MaybeHandle<SharedFunctionInfo> shared_info =
+                                 MaybeHandle<SharedFunctionInfo>());
   const Operator* Call(const CallDescriptor* descriptor);
   const Operator* TailCall(const CallDescriptor* descriptor);
   const Operator* Projection(size_t index);
Index: src/compiler/frame-states.cc
diff --git a/src/compiler/frame-states.cc b/src/compiler/frame-states.cc
index e5e35ab0a953d64f7304df01676e3c1ac35ccd3a..80876f6b2a9233f103645a69c2976ffeb8126b08 100644
--- a/src/compiler/frame-states.cc
+++ b/src/compiler/frame-states.cc
@@ -45,8 +45,13 @@ size_t hash_value(FrameStateCallInfo const& info) {


std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) {
-  return os << info.type() << ", " << info.bailout_id() << ", "
-            << info.state_combine();
+  os << info.type() << ", " << info.bailout_id() << ", "
+     << info.state_combine();
+  Handle<SharedFunctionInfo> shared_info;
+  if (info.shared_info().ToHandle(&shared_info)) {
+    os << ", " << Brief(*shared_info);
+  }
+  return os;
 }

 }  // namespace compiler
Index: src/compiler/frame-states.h
diff --git a/src/compiler/frame-states.h b/src/compiler/frame-states.h
index a1a002886fca238021f2120d19614b218e3837d8..20cb6427e76ce2369795f3c4a88f484f7ab89881 100644
--- a/src/compiler/frame-states.h
+++ b/src/compiler/frame-states.h
@@ -5,7 +5,7 @@
 #ifndef V8_COMPILER_FRAME_STATES_H_
 #define V8_COMPILER_FRAME_STATES_H_

-#include "src/utils.h"
+#include "src/handles-inl.h"

 namespace v8 {
 namespace internal {
@@ -79,19 +79,23 @@ enum FrameStateType {
 class FrameStateCallInfo final {
  public:
   FrameStateCallInfo(FrameStateType type, BailoutId bailout_id,
-                     OutputFrameStateCombine state_combine)
+                     OutputFrameStateCombine state_combine,
+                     MaybeHandle<SharedFunctionInfo> shared_info)
       : type_(type),
         bailout_id_(bailout_id),
-        frame_state_combine_(state_combine) {}
+        frame_state_combine_(state_combine),
+        shared_info_(shared_info) {}

   FrameStateType type() const { return type_; }
   BailoutId bailout_id() const { return bailout_id_; }
OutputFrameStateCombine state_combine() const { return frame_state_combine_; } + MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }

  private:
   FrameStateType const type_;
   BailoutId const bailout_id_;
   OutputFrameStateCombine const frame_state_combine_;
+  MaybeHandle<SharedFunctionInfo> const shared_info_;
 };

 bool operator==(FrameStateCallInfo const&, FrameStateCallInfo const&);
Index: src/compiler/instruction-selector.cc
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 43f5297a941713daeb51d485f8464be0a450b34f..ae9d4c6529e105215eb3c7b64b09c744c69a9673 100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -1052,7 +1052,8 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(

   return new (instruction_zone()) FrameStateDescriptor(
       instruction_zone(), state_info.type(), state_info.bailout_id(),
-      state_info.state_combine(), parameters, locals, stack, outer_state);
+      state_info.state_combine(), parameters, locals, stack,
+      state_info.shared_info(), outer_state);
 }


Index: src/compiler/instruction.cc
diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc
index 5b68d6590da6cafffe87698a9d3364445161fd8a..29a31e04774270e372b3dcb2f9ea15801c98754b 100644
--- a/src/compiler/instruction.cc
+++ b/src/compiler/instruction.cc
@@ -664,7 +664,9 @@ void InstructionSequence::SetSourcePosition(const Instruction* instr,
 FrameStateDescriptor::FrameStateDescriptor(
     Zone* zone, FrameStateType type, BailoutId bailout_id,
     OutputFrameStateCombine state_combine, size_t parameters_count,
- size_t locals_count, size_t stack_count, FrameStateDescriptor* outer_state)
+    size_t locals_count, size_t stack_count,
+    MaybeHandle<SharedFunctionInfo> shared_info,
+    FrameStateDescriptor* outer_state)
     : type_(type),
       bailout_id_(bailout_id),
       frame_state_combine_(state_combine),
@@ -672,6 +674,7 @@ FrameStateDescriptor::FrameStateDescriptor(
       locals_count_(locals_count),
       stack_count_(stack_count),
       types_(zone),
+      shared_info_(shared_info),
       outer_state_(outer_state) {
   types_.resize(GetSize(), kMachNone);
 }
Index: src/compiler/instruction.h
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h
index 10273a495c9f01870ed0f0e8eec06b6a433d9ba0..a107638b75b38c6bb5db2f90213103021b46d4d5 100644
--- a/src/compiler/instruction.h
+++ b/src/compiler/instruction.h
@@ -866,6 +866,7 @@ class FrameStateDescriptor : public ZoneObject {
                        OutputFrameStateCombine state_combine,
                        size_t parameters_count, size_t locals_count,
                        size_t stack_count,
+                       MaybeHandle<SharedFunctionInfo> shared_info,
                        FrameStateDescriptor* outer_state = nullptr);

   FrameStateType type() const { return type_; }
@@ -874,6 +875,7 @@ class FrameStateDescriptor : public ZoneObject {
   size_t parameters_count() const { return parameters_count_; }
   size_t locals_count() const { return locals_count_; }
   size_t stack_count() const { return stack_count_; }
+ MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }
   FrameStateDescriptor* outer_state() const { return outer_state_; }
   bool HasContext() const { return type_ == JS_FRAME; }

@@ -894,6 +896,7 @@ class FrameStateDescriptor : public ZoneObject {
   size_t locals_count_;
   size_t stack_count_;
   ZoneVector<MachineType> types_;
+  MaybeHandle<SharedFunctionInfo> const shared_info_;
   FrameStateDescriptor* outer_state_;
 };

@@ -1149,6 +1152,9 @@ class InstructionSequence final : public ZoneObject {
   StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor);
   FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id);
   int GetFrameStateDescriptorCount();
+  DeoptimizationVector const& frame_state_descriptors() const {
+    return deoptimization_entries_;
+  }

   RpoNumber InputRpo(Instruction* instr, size_t index);

Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 180eb63536c1f35bf5d07189478a81c55951d281..6048a02b2a3a9a96dab1783f0921ca56b0f9488b 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -11636,6 +11636,13 @@ WeakCell* Code::CachedWeakCell() {
 void DeoptimizationInputData::DeoptimizationInputDataPrint(
     std::ostream& os) {  // NOLINT
   disasm::NameConverter converter;
+  int const inlined_function_count = InlinedFunctionCount()->value();
+  os << "Inlined functions (count = " << inlined_function_count << ")\n";
+  for (int id = 0; id < inlined_function_count; ++id) {
+    Object* info = LiteralArray()->get(id);
+    os << " " << Brief(SharedFunctionInfo::cast(info)) << "\n";
+  }
+  os << "\n";
   int deopt_count = DeoptCount();
os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
   if (0 != deopt_count) {


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to