LCOV - code coverage report
Current view: top level - src/compiler - serializer-for-background-compilation.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 332 466 71.2 %
Date: 2019-04-17 Functions: 53 193 27.5 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/serializer-for-background-compilation.h"
       6             : 
       7             : #include <sstream>
       8             : 
       9             : #include "src/compiler/js-heap-broker.h"
      10             : #include "src/handles-inl.h"
      11             : #include "src/interpreter/bytecode-array-iterator.h"
      12             : #include "src/objects/code.h"
      13             : #include "src/objects/shared-function-info-inl.h"
      14             : #include "src/vector-slot-pair.h"
      15             : #include "src/zone/zone.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace compiler {
      20             : 
      21             : using BytecodeArrayIterator = interpreter::BytecodeArrayIterator;
      22             : 
      23         153 : CompilationSubject::CompilationSubject(Handle<JSFunction> closure,
      24             :                                        Isolate* isolate)
      25             :     : blueprint_{handle(closure->shared(), isolate),
      26             :                  handle(closure->feedback_vector(), isolate)},
      27         306 :       closure_(closure) {
      28         153 :   CHECK(closure->has_feedback_vector());
      29         153 : }
      30             : 
      31           0 : Hints::Hints(Zone* zone)
      32           0 :     : constants_(zone), maps_(zone), function_blueprints_(zone) {}
      33             : 
      34           0 : const ConstantsSet& Hints::constants() const { return constants_; }
      35             : 
      36          17 : const MapsSet& Hints::maps() const { return maps_; }
      37             : 
      38           0 : const BlueprintsSet& Hints::function_blueprints() const {
      39           0 :   return function_blueprints_;
      40             : }
      41             : 
      42           0 : void Hints::AddConstant(Handle<Object> constant) {
      43             :   constants_.insert(constant);
      44           0 : }
      45             : 
      46           0 : void Hints::AddMap(Handle<Map> map) { maps_.insert(map); }
      47             : 
      48           0 : void Hints::AddFunctionBlueprint(FunctionBlueprint function_blueprint) {
      49             :   function_blueprints_.insert(function_blueprint);
      50           0 : }
      51             : 
      52         665 : void Hints::Add(const Hints& other) {
      53         964 :   for (auto x : other.constants()) AddConstant(x);
      54         665 :   for (auto x : other.maps()) AddMap(x);
      55         726 :   for (auto x : other.function_blueprints()) AddFunctionBlueprint(x);
      56         665 : }
      57             : 
      58           0 : bool Hints::IsEmpty() const {
      59           0 :   return constants().empty() && maps().empty() && function_blueprints().empty();
      60             : }
      61             : 
      62           0 : std::ostream& operator<<(std::ostream& out,
      63             :                          const FunctionBlueprint& blueprint) {
      64           0 :   out << Brief(*blueprint.shared) << std::endl;
      65           0 :   out << Brief(*blueprint.feedback_vector) << std::endl;
      66           0 :   return out;
      67             : }
      68             : 
      69           0 : std::ostream& operator<<(std::ostream& out, const Hints& hints) {
      70             :   !hints.constants().empty() &&
      71           0 :       out << "\t\tConstants (" << hints.constants().size() << "):" << std::endl;
      72           0 :   for (auto x : hints.constants()) out << Brief(*x) << std::endl;
      73             :   !hints.maps().empty() && out << "\t\tMaps (" << hints.maps().size()
      74           0 :                                << "):" << std::endl;
      75           0 :   for (auto x : hints.maps()) out << Brief(*x) << std::endl;
      76             :   !hints.function_blueprints().empty() &&
      77             :       out << "\t\tBlueprints (" << hints.function_blueprints().size()
      78           0 :           << "):" << std::endl;
      79           0 :   for (auto x : hints.function_blueprints()) out << x;
      80           0 :   return out;
      81             : }
      82             : 
      83        2025 : void Hints::Clear() {
      84             :   constants_.clear();
      85             :   maps_.clear();
      86             :   function_blueprints_.clear();
      87             :   DCHECK(IsEmpty());
      88        2025 : }
      89             : 
      90          32 : class SerializerForBackgroundCompilation::Environment : public ZoneObject {
      91             :  public:
      92             :   Environment(Zone* zone, CompilationSubject function);
      93             :   Environment(Zone* zone, Isolate* isolate, CompilationSubject function,
      94             :               base::Optional<Hints> new_target, const HintsVector& arguments);
      95             : 
      96             :   // When control flow bytecodes are encountered, e.g. a conditional jump,
      97             :   // the current environment needs to be stashed together with the target jump
      98             :   // address. Later, when this target bytecode is handled, the stashed
      99             :   // environment will be merged into the current one.
     100             :   void Merge(Environment* other);
     101             : 
     102             :   friend std::ostream& operator<<(std::ostream& out, const Environment& env);
     103             : 
     104             :   FunctionBlueprint function() const { return function_; }
     105             : 
     106        1268 :   Hints& accumulator_hints() { return environment_hints_[accumulator_index()]; }
     107             :   Hints& register_hints(interpreter::Register reg) {
     108         761 :     int local_index = RegisterToLocalIndex(reg);
     109             :     DCHECK_LT(local_index, environment_hints_.size());
     110         761 :     return environment_hints_[local_index];
     111             :   }
     112         324 :   Hints& return_value_hints() { return return_value_hints_; }
     113             : 
     114             :   // Clears all hints except those for the return value and the closure.
     115         224 :   void ClearEphemeralHints() {
     116             :     DCHECK_EQ(environment_hints_.size(), function_closure_index() + 1);
     117        2710 :     for (int i = 0; i < function_closure_index(); ++i) {
     118        2486 :       environment_hints_[i].Clear();
     119             :     }
     120         224 :   }
     121             : 
     122             :   // Appends the hints for the given register range to {dst} (in order).
     123             :   void ExportRegisterHints(interpreter::Register first, size_t count,
     124             :                            HintsVector& dst);
     125             : 
     126             :  private:
     127             :   int RegisterToLocalIndex(interpreter::Register reg) const;
     128             : 
     129             :   Zone* zone() const { return zone_; }
     130             :   int parameter_count() const { return parameter_count_; }
     131             :   int register_count() const { return register_count_; }
     132             : 
     133             :   Zone* const zone_;
     134             :   // Instead of storing the blueprint here, we could extract it from the
     135             :   // (closure) hints but that would be cumbersome.
     136             :   FunctionBlueprint const function_;
     137             :   int const parameter_count_;
     138             :   int const register_count_;
     139             : 
     140             :   // environment_hints_ contains hints for the contents of the registers,
     141             :   // the accumulator and the parameters. The layout is as follows:
     142             :   // [ parameters | registers | accumulator | context | closure ]
     143             :   // The first parameter is the receiver.
     144             :   HintsVector environment_hints_;
     145        3121 :   int accumulator_index() const { return parameter_count() + register_count(); }
     146           1 :   int current_context_index() const { return accumulator_index() + 1; }
     147        1649 :   int function_closure_index() const { return current_context_index() + 1; }
     148         203 :   int environment_hints_size() const { return function_closure_index() + 1; }
     149             : 
     150             :   Hints return_value_hints_;
     151             : };
     152             : 
     153         171 : SerializerForBackgroundCompilation::Environment::Environment(
     154             :     Zone* zone, CompilationSubject function)
     155             :     : zone_(zone),
     156             :       function_(function.blueprint()),
     157         342 :       parameter_count_(function_.shared->GetBytecodeArray()->parameter_count()),
     158         342 :       register_count_(function_.shared->GetBytecodeArray()->register_count()),
     159             :       environment_hints_(environment_hints_size(), Hints(zone), zone),
     160         855 :       return_value_hints_(zone) {
     161             :   Handle<JSFunction> closure;
     162         171 :   if (function.closure().ToHandle(&closure)) {
     163         153 :     environment_hints_[function_closure_index()].AddConstant(closure);
     164             :   } else {
     165          18 :     environment_hints_[function_closure_index()].AddFunctionBlueprint(
     166             :         function.blueprint());
     167             :   }
     168         171 : }
     169             : 
     170          87 : SerializerForBackgroundCompilation::Environment::Environment(
     171             :     Zone* zone, Isolate* isolate, CompilationSubject function,
     172             :     base::Optional<Hints> new_target, const HintsVector& arguments)
     173          87 :     : Environment(zone, function) {
     174             :   // Copy the hints for the actually passed arguments, at most up to
     175             :   // the parameter_count.
     176          87 :   size_t param_count = static_cast<size_t>(parameter_count());
     177         588 :   for (size_t i = 0; i < std::min(arguments.size(), param_count); ++i) {
     178         138 :     environment_hints_[i] = arguments[i];
     179             :   }
     180             : 
     181             :   // Pad the rest with "undefined".
     182          87 :   Hints undefined_hint(zone);
     183             :   undefined_hint.AddConstant(isolate->factory()->undefined_value());
     184         125 :   for (size_t i = arguments.size(); i < param_count; ++i) {
     185          19 :     environment_hints_[i] = undefined_hint;
     186             :   }
     187             : 
     188             :   interpreter::Register new_target_reg =
     189         174 :       function_.shared->GetBytecodeArray()
     190             :           ->incoming_new_target_or_generator_register();
     191          87 :   if (new_target_reg.is_valid()) {
     192             :     DCHECK(register_hints(new_target_reg).IsEmpty());
     193          10 :     if (new_target.has_value()) {
     194          10 :       register_hints(new_target_reg).Add(*new_target);
     195             :     }
     196             :   }
     197          87 : }
     198             : 
     199          16 : void SerializerForBackgroundCompilation::Environment::Merge(
     200             :     Environment* other) {
     201             :   // Presumably the source and the target would have the same layout
     202             :   // so this is enforced here.
     203          16 :   CHECK_EQ(parameter_count(), other->parameter_count());
     204          16 :   CHECK_EQ(register_count(), other->register_count());
     205          16 :   CHECK_EQ(environment_hints_size(), other->environment_hints_size());
     206             : 
     207         232 :   for (size_t i = 0; i < environment_hints_.size(); ++i) {
     208         108 :     environment_hints_[i].Add(other->environment_hints_[i]);
     209             :   }
     210          16 :   return_value_hints_.Add(other->return_value_hints_);
     211          16 : }
     212             : 
     213           0 : std::ostream& operator<<(
     214             :     std::ostream& out,
     215             :     const SerializerForBackgroundCompilation::Environment& env) {
     216           0 :   std::ostringstream output_stream;
     217           0 :   output_stream << "Function ";
     218           0 :   env.function_.shared->Name()->Print(output_stream);
     219           0 :   output_stream << "Parameter count: " << env.parameter_count() << std::endl;
     220           0 :   output_stream << "Register count: " << env.register_count() << std::endl;
     221             : 
     222           0 :   output_stream << "Hints (" << env.environment_hints_.size() << "):\n";
     223           0 :   for (size_t i = 0; i < env.environment_hints_.size(); ++i) {
     224           0 :     if (env.environment_hints_[i].IsEmpty()) continue;
     225             : 
     226             :     output_stream << "\tSlot " << i << std::endl;
     227           0 :     output_stream << env.environment_hints_[i];
     228             :   }
     229           0 :   output_stream << "Return value:\n";
     230           0 :   output_stream << env.return_value_hints_
     231           0 :                 << "===========================================\n";
     232             : 
     233           0 :   out << output_stream.str();
     234           0 :   return out;
     235             : }
     236             : 
     237         761 : int SerializerForBackgroundCompilation::Environment::RegisterToLocalIndex(
     238             :     interpreter::Register reg) const {
     239             :   // TODO(mslekova): We also want to gather hints for the context.
     240         762 :   if (reg.is_current_context()) return current_context_index();
     241         771 :   if (reg.is_function_closure()) return function_closure_index();
     242         749 :   if (reg.is_parameter()) {
     243          35 :     return reg.ToParameterIndex(parameter_count());
     244             :   } else {
     245         714 :     return parameter_count() + reg.index();
     246             :   }
     247             : }
     248             : 
     249          84 : SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
     250             :     JSHeapBroker* broker, Zone* zone, Handle<JSFunction> closure)
     251             :     : broker_(broker),
     252             :       zone_(zone),
     253          84 :       environment_(new (zone) Environment(zone, {closure, broker_->isolate()})),
     254         168 :       stashed_environments_(zone) {
     255          84 :   JSFunctionRef(broker, closure).Serialize();
     256          84 : }
     257             : 
     258          87 : SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
     259             :     JSHeapBroker* broker, Zone* zone, CompilationSubject function,
     260             :     base::Optional<Hints> new_target, const HintsVector& arguments)
     261             :     : broker_(broker),
     262             :       zone_(zone),
     263             :       environment_(new (zone) Environment(zone, broker_->isolate(), function,
     264          87 :                                           new_target, arguments)),
     265         261 :       stashed_environments_(zone) {
     266             :   Handle<JSFunction> closure;
     267          87 :   if (function.closure().ToHandle(&closure)) {
     268          69 :     JSFunctionRef(broker, closure).Serialize();
     269             :   }
     270          87 : }
     271             : 
     272         171 : Hints SerializerForBackgroundCompilation::Run() {
     273             :   SharedFunctionInfoRef shared(broker(), environment()->function().shared);
     274             :   FeedbackVectorRef feedback_vector(broker(),
     275             :                                     environment()->function().feedback_vector);
     276         171 :   if (shared.IsSerializedForCompilation(feedback_vector)) {
     277             :     return Hints(zone());
     278             :   }
     279         162 :   shared.SetSerializedForCompilation(feedback_vector);
     280         162 :   feedback_vector.SerializeSlots();
     281         162 :   TraverseBytecode();
     282         162 :   return environment()->return_value_hints();
     283             : }
     284             : 
     285         162 : void SerializerForBackgroundCompilation::TraverseBytecode() {
     286             :   BytecodeArrayRef bytecode_array(
     287             :       broker(), handle(environment()->function().shared->GetBytecodeArray(),
     288         324 :                        broker()->isolate()));
     289         162 :   BytecodeArrayIterator iterator(bytecode_array.object());
     290             : 
     291        2760 :   for (; !iterator.done(); iterator.Advance()) {
     292        1299 :     MergeAfterJump(&iterator);
     293        1299 :     switch (iterator.current_bytecode()) {
     294             : #define DEFINE_BYTECODE_CASE(name)     \
     295             :   case interpreter::Bytecode::k##name: \
     296             :     Visit##name(&iterator);            \
     297             :     break;
     298         240 :       SUPPORTED_BYTECODE_LIST(DEFINE_BYTECODE_CASE)
     299             : #undef DEFINE_BYTECODE_CASE
     300             :       default: {
     301          13 :         environment()->ClearEphemeralHints();
     302          13 :         break;
     303             :       }
     304             :     }
     305             :   }
     306         162 : }
     307             : 
     308           0 : void SerializerForBackgroundCompilation::VisitIllegal(
     309             :     BytecodeArrayIterator* iterator) {
     310           0 :   UNREACHABLE();
     311             : }
     312             : 
     313           0 : void SerializerForBackgroundCompilation::VisitWide(
     314             :     BytecodeArrayIterator* iterator) {
     315           0 :   UNREACHABLE();
     316             : }
     317             : 
     318           0 : void SerializerForBackgroundCompilation::VisitExtraWide(
     319             :     BytecodeArrayIterator* iterator) {
     320           0 :   UNREACHABLE();
     321             : }
     322             : 
     323           5 : void SerializerForBackgroundCompilation::VisitGetSuperConstructor(
     324             :     BytecodeArrayIterator* iterator) {
     325           5 :   interpreter::Register dst = iterator->GetRegisterOperand(0);
     326           5 :   environment()->register_hints(dst).Clear();
     327             : 
     328          10 :   for (auto constant : environment()->accumulator_hints().constants()) {
     329             :     // For JSNativeContextSpecialization::ReduceJSGetSuperConstructor.
     330           5 :     if (!constant->IsJSFunction()) continue;
     331             :     MapRef map(broker(),
     332             :                handle(HeapObject::cast(*constant)->map(), broker()->isolate()));
     333           5 :     map.SerializePrototype();
     334           5 :     ObjectRef proto = map.prototype();
     335           5 :     if (proto.IsHeapObject() && proto.AsHeapObject().map().is_constructor()) {
     336           5 :       environment()->register_hints(dst).AddConstant(proto.object());
     337             :     }
     338             :   }
     339           5 : }
     340             : 
     341           0 : void SerializerForBackgroundCompilation::VisitLdaTrue(
     342             :     BytecodeArrayIterator* iterator) {
     343           0 :   environment()->accumulator_hints().Clear();
     344             :   environment()->accumulator_hints().AddConstant(
     345             :       broker()->isolate()->factory()->true_value());
     346           0 : }
     347             : 
     348           0 : void SerializerForBackgroundCompilation::VisitLdaFalse(
     349             :     BytecodeArrayIterator* iterator) {
     350           0 :   environment()->accumulator_hints().Clear();
     351             :   environment()->accumulator_hints().AddConstant(
     352             :       broker()->isolate()->factory()->false_value());
     353           0 : }
     354             : 
     355           1 : void SerializerForBackgroundCompilation::VisitLdaTheHole(
     356             :     BytecodeArrayIterator* iterator) {
     357           1 :   environment()->accumulator_hints().Clear();
     358             :   environment()->accumulator_hints().AddConstant(
     359             :       broker()->isolate()->factory()->the_hole_value());
     360           1 : }
     361             : 
     362          84 : void SerializerForBackgroundCompilation::VisitLdaUndefined(
     363             :     BytecodeArrayIterator* iterator) {
     364          84 :   environment()->accumulator_hints().Clear();
     365             :   environment()->accumulator_hints().AddConstant(
     366             :       broker()->isolate()->factory()->undefined_value());
     367          84 : }
     368             : 
     369           0 : void SerializerForBackgroundCompilation::VisitLdaNull(
     370             :     BytecodeArrayIterator* iterator) {
     371           0 :   environment()->accumulator_hints().Clear();
     372             :   environment()->accumulator_hints().AddConstant(
     373             :       broker()->isolate()->factory()->null_value());
     374           0 : }
     375             : 
     376          23 : void SerializerForBackgroundCompilation::VisitLdaZero(
     377             :     BytecodeArrayIterator* iterator) {
     378          23 :   environment()->accumulator_hints().Clear();
     379             :   environment()->accumulator_hints().AddConstant(
     380             :       handle(Smi::FromInt(0), broker()->isolate()));
     381          23 : }
     382             : 
     383          42 : void SerializerForBackgroundCompilation::VisitLdaSmi(
     384             :     BytecodeArrayIterator* iterator) {
     385          42 :   environment()->accumulator_hints().Clear();
     386          42 :   environment()->accumulator_hints().AddConstant(handle(
     387             :       Smi::FromInt(iterator->GetImmediateOperand(0)), broker()->isolate()));
     388          42 : }
     389             : 
     390           7 : void SerializerForBackgroundCompilation::VisitLdaConstant(
     391             :     BytecodeArrayIterator* iterator) {
     392           7 :   environment()->accumulator_hints().Clear();
     393           7 :   environment()->accumulator_hints().AddConstant(
     394             :       handle(iterator->GetConstantForIndexOperand(0), broker()->isolate()));
     395           7 : }
     396             : 
     397          45 : void SerializerForBackgroundCompilation::VisitLdar(
     398             :     BytecodeArrayIterator* iterator) {
     399          45 :   environment()->accumulator_hints().Clear();
     400             :   environment()->accumulator_hints().Add(
     401          90 :       environment()->register_hints(iterator->GetRegisterOperand(0)));
     402          45 : }
     403             : 
     404         220 : void SerializerForBackgroundCompilation::VisitStar(
     405             :     BytecodeArrayIterator* iterator) {
     406         220 :   interpreter::Register reg = iterator->GetRegisterOperand(0);
     407         220 :   environment()->register_hints(reg).Clear();
     408         220 :   environment()->register_hints(reg).Add(environment()->accumulator_hints());
     409         220 : }
     410             : 
     411          17 : void SerializerForBackgroundCompilation::VisitMov(
     412             :     BytecodeArrayIterator* iterator) {
     413          17 :   interpreter::Register src = iterator->GetRegisterOperand(0);
     414          17 :   interpreter::Register dst = iterator->GetRegisterOperand(1);
     415          17 :   environment()->register_hints(dst).Clear();
     416          17 :   environment()->register_hints(dst).Add(environment()->register_hints(src));
     417          17 : }
     418             : 
     419          69 : void SerializerForBackgroundCompilation::VisitCreateClosure(
     420             :     BytecodeArrayIterator* iterator) {
     421             :   Handle<SharedFunctionInfo> shared(
     422             :       SharedFunctionInfo::cast(iterator->GetConstantForIndexOperand(0)),
     423          69 :       broker()->isolate());
     424             : 
     425             :   Handle<FeedbackCell> feedback_cell =
     426             :       environment()->function().feedback_vector->GetClosureFeedbackCell(
     427          69 :           iterator->GetIndexOperand(1));
     428             :   Handle<Object> cell_value(feedback_cell->value(), broker()->isolate());
     429             : 
     430          69 :   environment()->accumulator_hints().Clear();
     431          69 :   if (cell_value->IsFeedbackVector()) {
     432             :     environment()->accumulator_hints().AddFunctionBlueprint(
     433             :         {shared, Handle<FeedbackVector>::cast(cell_value)});
     434             :   }
     435          69 : }
     436             : 
     437           4 : void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver(
     438             :     BytecodeArrayIterator* iterator) {
     439           4 :   ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
     440           4 : }
     441             : 
     442          24 : void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
     443             :     BytecodeArrayIterator* iterator) {
     444             :   const Hints& callee =
     445          24 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     446          24 :   FeedbackSlot slot = iterator->GetSlotOperand(1);
     447             : 
     448          24 :   Hints receiver(zone());
     449             :   receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
     450             : 
     451          72 :   HintsVector parameters({receiver}, zone());
     452          48 :   ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
     453          24 : }
     454             : 
     455          19 : void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1(
     456             :     BytecodeArrayIterator* iterator) {
     457             :   const Hints& callee =
     458          19 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     459             :   const Hints& arg0 =
     460          19 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     461          19 :   FeedbackSlot slot = iterator->GetSlotOperand(2);
     462             : 
     463          19 :   Hints receiver(zone());
     464             :   receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
     465             : 
     466          76 :   HintsVector parameters({receiver, arg0}, zone());
     467          38 :   ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
     468          19 : }
     469             : 
     470           4 : void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
     471             :     BytecodeArrayIterator* iterator) {
     472             :   const Hints& callee =
     473           4 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     474             :   const Hints& arg0 =
     475           4 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     476             :   const Hints& arg1 =
     477           4 :       environment()->register_hints(iterator->GetRegisterOperand(2));
     478           4 :   FeedbackSlot slot = iterator->GetSlotOperand(3);
     479             : 
     480           4 :   Hints receiver(zone());
     481             :   receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
     482             : 
     483          20 :   HintsVector parameters({receiver, arg0, arg1}, zone());
     484           8 :   ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
     485           4 : }
     486             : 
     487           4 : void SerializerForBackgroundCompilation::VisitCallAnyReceiver(
     488             :     BytecodeArrayIterator* iterator) {
     489           4 :   ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny);
     490           4 : }
     491             : 
     492           4 : void SerializerForBackgroundCompilation::VisitCallProperty(
     493             :     BytecodeArrayIterator* iterator) {
     494           4 :   ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined);
     495           4 : }
     496             : 
     497           0 : void SerializerForBackgroundCompilation::VisitCallProperty0(
     498             :     BytecodeArrayIterator* iterator) {
     499             :   const Hints& callee =
     500           0 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     501             :   const Hints& receiver =
     502           0 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     503           0 :   FeedbackSlot slot = iterator->GetSlotOperand(2);
     504             : 
     505           0 :   HintsVector parameters({receiver}, zone());
     506           0 :   ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
     507           0 : }
     508             : 
     509           0 : void SerializerForBackgroundCompilation::VisitCallProperty1(
     510             :     BytecodeArrayIterator* iterator) {
     511             :   const Hints& callee =
     512           0 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     513             :   const Hints& receiver =
     514           0 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     515             :   const Hints& arg0 =
     516           0 :       environment()->register_hints(iterator->GetRegisterOperand(2));
     517           0 :   FeedbackSlot slot = iterator->GetSlotOperand(3);
     518             : 
     519           0 :   HintsVector parameters({receiver, arg0}, zone());
     520           0 :   ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
     521           0 : }
     522             : 
     523           4 : void SerializerForBackgroundCompilation::VisitCallProperty2(
     524             :     BytecodeArrayIterator* iterator) {
     525             :   const Hints& callee =
     526           4 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     527             :   const Hints& receiver =
     528           4 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     529             :   const Hints& arg0 =
     530           4 :       environment()->register_hints(iterator->GetRegisterOperand(2));
     531             :   const Hints& arg1 =
     532           4 :       environment()->register_hints(iterator->GetRegisterOperand(3));
     533           4 :   FeedbackSlot slot = iterator->GetSlotOperand(4);
     534             : 
     535          20 :   HintsVector parameters({receiver, arg0, arg1}, zone());
     536           8 :   ProcessCallOrConstruct(callee, base::nullopt, parameters, slot);
     537           4 : }
     538             : 
     539           4 : void SerializerForBackgroundCompilation::VisitCallWithSpread(
     540             :     BytecodeArrayIterator* iterator) {
     541           4 :   ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny, true);
     542           4 : }
     543             : 
     544          91 : Hints SerializerForBackgroundCompilation::RunChildSerializer(
     545             :     CompilationSubject function, base::Optional<Hints> new_target,
     546             :     const HintsVector& arguments, bool with_spread) {
     547          91 :   if (with_spread) {
     548             :     DCHECK_LT(0, arguments.size());
     549             :     // Pad the missing arguments in case we were called with spread operator.
     550             :     // Drop the last actually passed argument, which contains the spread.
     551             :     // We don't know what the spread element produces. Therefore we pretend
     552             :     // that the function is called with the maximal number of parameters and
     553             :     // that we have no information about the parameters that were not
     554             :     // explicitly provided.
     555             :     HintsVector padded = arguments;
     556             :     padded.pop_back();  // Remove the spread element.
     557             :     // Fill the rest with empty hints.
     558           8 :     padded.resize(
     559           8 :         function.blueprint().shared->GetBytecodeArray()->parameter_count(),
     560           4 :         Hints(zone()));
     561           8 :     return RunChildSerializer(function, new_target, padded, false);
     562             :   }
     563             : 
     564          87 :   TRACE_BROKER(broker(), "Will run child serializer with environment:\n"
     565             :                              << *environment());
     566             : 
     567             :   SerializerForBackgroundCompilation child_serializer(
     568         174 :       broker(), zone(), function, new_target, arguments);
     569          87 :   return child_serializer.Run();
     570             : }
     571             : 
     572             : namespace {
     573          85 : base::Optional<HeapObjectRef> GetHeapObjectFeedback(
     574             :     JSHeapBroker* broker, Handle<FeedbackVector> feedback_vector,
     575             :     FeedbackSlot slot) {
     576          85 :   if (slot.IsInvalid()) return base::nullopt;
     577             :   FeedbackNexus nexus(feedback_vector, slot);
     578          85 :   VectorSlotPair feedback(feedback_vector, slot, nexus.ic_state());
     579             :   DCHECK(feedback.IsValid());
     580          85 :   if (nexus.IsUninitialized()) return base::nullopt;
     581             :   HeapObject object;
     582         156 :   if (!nexus.GetFeedback()->GetHeapObject(&object)) return base::nullopt;
     583          78 :   return HeapObjectRef(broker, handle(object, broker->isolate()));
     584             : }
     585             : }  // namespace
     586             : 
     587          85 : void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
     588             :     Hints callee, base::Optional<Hints> new_target,
     589             :     const HintsVector& arguments, FeedbackSlot slot, bool with_spread) {
     590             :   // Incorporate feedback into hints.
     591             :   base::Optional<HeapObjectRef> feedback = GetHeapObjectFeedback(
     592          85 :       broker(), environment()->function().feedback_vector, slot);
     593          85 :   if (feedback.has_value() && feedback->map().is_callable()) {
     594          64 :     if (new_target.has_value()) {
     595             :       // Construct; feedback is new_target, which often is also the callee.
     596          18 :       new_target->AddConstant(feedback->object());
     597          18 :       callee.AddConstant(feedback->object());
     598             :     } else {
     599             :       // Call; feedback is callee.
     600          46 :       callee.AddConstant(feedback->object());
     601             :     }
     602             :   }
     603             : 
     604          85 :   environment()->accumulator_hints().Clear();
     605             : 
     606         154 :   for (auto hint : callee.constants()) {
     607          69 :     if (!hint->IsJSFunction()) continue;
     608             : 
     609             :     Handle<JSFunction> function = Handle<JSFunction>::cast(hint);
     610         138 :     if (!function->shared()->IsInlineable() || !function->has_feedback_vector())
     611             :       continue;
     612             : 
     613         276 :     environment()->accumulator_hints().Add(RunChildSerializer(
     614          69 :         {function, broker()->isolate()}, new_target, arguments, with_spread));
     615             :   }
     616             : 
     617         103 :   for (auto hint : callee.function_blueprints()) {
     618          18 :     if (!hint.shared->IsInlineable()) continue;
     619          72 :     environment()->accumulator_hints().Add(RunChildSerializer(
     620          18 :         CompilationSubject(hint), new_target, arguments, with_spread));
     621             :   }
     622          85 : }
     623             : 
     624          16 : void SerializerForBackgroundCompilation::ProcessCallVarArgs(
     625             :     BytecodeArrayIterator* iterator, ConvertReceiverMode receiver_mode,
     626             :     bool with_spread) {
     627             :   const Hints& callee =
     628          16 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     629          16 :   interpreter::Register first_reg = iterator->GetRegisterOperand(1);
     630          16 :   int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
     631          16 :   FeedbackSlot slot = iterator->GetSlotOperand(3);
     632             : 
     633             :   HintsVector arguments(zone());
     634             :   // The receiver is either given in the first register or it is implicitly
     635             :   // the {undefined} value.
     636          16 :   if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
     637           8 :     Hints receiver(zone());
     638             :     receiver.AddConstant(broker()->isolate()->factory()->undefined_value());
     639           8 :     arguments.push_back(receiver);
     640             :   }
     641          16 :   environment()->ExportRegisterHints(first_reg, reg_count, arguments);
     642             : 
     643          32 :   ProcessCallOrConstruct(callee, base::nullopt, arguments, slot);
     644          16 : }
     645             : 
     646          16 : void SerializerForBackgroundCompilation::ProcessJump(
     647             :     interpreter::BytecodeArrayIterator* iterator) {
     648          16 :   int jump_target = iterator->GetJumpTargetOffset();
     649             :   int current_offset = iterator->current_offset();
     650          16 :   if (current_offset >= jump_target) return;
     651             : 
     652          32 :   stashed_environments_[jump_target] = new (zone()) Environment(*environment());
     653             : }
     654             : 
     655        1299 : void SerializerForBackgroundCompilation::MergeAfterJump(
     656             :     interpreter::BytecodeArrayIterator* iterator) {
     657        1299 :   int current_offset = iterator->current_offset();
     658             :   auto stash = stashed_environments_.find(current_offset);
     659        1299 :   if (stash != stashed_environments_.end()) {
     660          16 :     environment()->Merge(stash->second);
     661             :     stashed_environments_.erase(stash);
     662             :   }
     663        1299 : }
     664             : 
     665         162 : void SerializerForBackgroundCompilation::VisitReturn(
     666             :     BytecodeArrayIterator* iterator) {
     667         162 :   environment()->return_value_hints().Add(environment()->accumulator_hints());
     668         162 :   environment()->ClearEphemeralHints();
     669         162 : }
     670             : 
     671          34 : void SerializerForBackgroundCompilation::Environment::ExportRegisterHints(
     672             :     interpreter::Register first, size_t count, HintsVector& dst) {
     673          34 :   dst.resize(dst.size() + count, Hints(zone()));
     674             :   int reg_base = first.index();
     675         130 :   for (int i = 0; i < static_cast<int>(count); ++i) {
     676          96 :     dst.push_back(register_hints(interpreter::Register(reg_base + i)));
     677             :   }
     678          34 : }
     679             : 
     680          14 : void SerializerForBackgroundCompilation::VisitConstruct(
     681             :     BytecodeArrayIterator* iterator) {
     682             :   const Hints& callee =
     683          14 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     684          14 :   interpreter::Register first_reg = iterator->GetRegisterOperand(1);
     685          14 :   size_t reg_count = iterator->GetRegisterCountOperand(2);
     686          14 :   FeedbackSlot slot = iterator->GetSlotOperand(3);
     687             :   const Hints& new_target = environment()->accumulator_hints();
     688             : 
     689             :   HintsVector arguments(zone());
     690          14 :   environment()->ExportRegisterHints(first_reg, reg_count, arguments);
     691             : 
     692          28 :   ProcessCallOrConstruct(callee, new_target, arguments, slot);
     693          14 : }
     694             : 
     695           4 : void SerializerForBackgroundCompilation::VisitConstructWithSpread(
     696             :     BytecodeArrayIterator* iterator) {
     697             :   const Hints& callee =
     698           4 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     699           4 :   interpreter::Register first_reg = iterator->GetRegisterOperand(1);
     700           4 :   size_t reg_count = iterator->GetRegisterCountOperand(2);
     701           4 :   FeedbackSlot slot = iterator->GetSlotOperand(3);
     702             :   const Hints& new_target = environment()->accumulator_hints();
     703             : 
     704             :   HintsVector arguments(zone());
     705           4 :   environment()->ExportRegisterHints(first_reg, reg_count, arguments);
     706             : 
     707           8 :   ProcessCallOrConstruct(callee, new_target, arguments, slot, true);
     708           4 : }
     709             : 
     710             : GlobalAccessFeedback const*
     711          51 : SerializerForBackgroundCompilation::ProcessFeedbackForGlobalAccess(
     712             :     FeedbackSlot slot) {
     713          51 :   if (slot.IsInvalid()) return nullptr;
     714          51 :   if (environment()->function().feedback_vector.is_null()) return nullptr;
     715             :   FeedbackSource source(environment()->function().feedback_vector, slot);
     716             : 
     717          51 :   if (broker()->HasFeedback(source)) {
     718           4 :     return broker()->GetGlobalAccessFeedback(source);
     719             :   }
     720             : 
     721             :   const GlobalAccessFeedback* feedback =
     722          47 :       broker()->ProcessFeedbackForGlobalAccess(source);
     723          47 :   broker()->SetFeedback(source, feedback);
     724          47 :   return feedback;
     725             : }
     726             : 
     727          16 : void SerializerForBackgroundCompilation::VisitLdaGlobal(
     728             :     BytecodeArrayIterator* iterator) {
     729          16 :   FeedbackSlot slot = iterator->GetSlotOperand(1);
     730          16 :   environment()->accumulator_hints().Clear();
     731          16 :   GlobalAccessFeedback const* feedback = ProcessFeedbackForGlobalAccess(slot);
     732          16 :   if (feedback != nullptr) {
     733             :     // We may be able to contribute to accumulator constant hints.
     734           0 :     base::Optional<ObjectRef> value = feedback->GetConstantHint();
     735           0 :     if (value.has_value()) {
     736           0 :       environment()->accumulator_hints().AddConstant(value->object());
     737             :     }
     738             :   }
     739          16 : }
     740             : 
     741           0 : void SerializerForBackgroundCompilation::VisitLdaGlobalInsideTypeof(
     742             :     BytecodeArrayIterator* iterator) {
     743           0 :   VisitLdaGlobal(iterator);
     744           0 : }
     745             : 
     746           0 : void SerializerForBackgroundCompilation::VisitLdaLookupGlobalSlot(
     747             :     BytecodeArrayIterator* iterator) {
     748           0 :   VisitLdaGlobal(iterator);
     749           0 : }
     750             : 
     751           0 : void SerializerForBackgroundCompilation::VisitLdaLookupGlobalSlotInsideTypeof(
     752             :     BytecodeArrayIterator* iterator) {
     753           0 :   VisitLdaGlobal(iterator);
     754           0 : }
     755             : 
     756           0 : void SerializerForBackgroundCompilation::VisitStaGlobal(
     757             :     BytecodeArrayIterator* iterator) {
     758          35 :   FeedbackSlot slot = iterator->GetSlotOperand(1);
     759          35 :   ProcessFeedbackForGlobalAccess(slot);
     760           0 : }
     761             : 
     762             : namespace {
     763             : template <class MapContainer>
     764          42 : MapHandles GetRelevantReceiverMaps(Isolate* isolate, MapContainer const& maps) {
     765             :   MapHandles result;
     766          50 :   for (Handle<Map> map : maps) {
     767          32 :     if (Map::TryUpdate(isolate, map).ToHandle(&map) &&
     768          16 :         !map->is_abandoned_prototype_map()) {
     769             :       DCHECK(!map->is_deprecated());
     770           8 :       result.push_back(map);
     771             :     }
     772             :   }
     773          42 :   return result;
     774             : }
     775             : }  // namespace
     776             : 
     777             : // Note: We never use the same feedback slot for multiple access modes.
     778          16 : void SerializerForBackgroundCompilation::ProcessFeedbackForKeyedPropertyAccess(
     779             :     FeedbackSlot slot, AccessMode mode) {
     780          32 :   if (slot.IsInvalid()) return;
     781          16 :   if (environment()->function().feedback_vector.is_null()) return;
     782             : 
     783             :   FeedbackNexus nexus(environment()->function().feedback_vector, slot);
     784          16 :   FeedbackSource source(nexus);
     785          16 :   if (broker()->HasFeedback(source)) return;
     786             : 
     787          16 :   if (nexus.GetKeyType() == PROPERTY) {
     788           0 :     CHECK_NE(mode, AccessMode::kStoreInLiteral);
     789             :     return;  // TODO(neis): Support named access.
     790             :   }
     791             :   DCHECK_EQ(nexus.GetKeyType(), ELEMENT);
     792          32 :   CHECK(nexus.GetName().is_null());
     793             : 
     794             :   MapHandles maps;
     795          16 :   nexus.ExtractMaps(&maps);
     796             :   ElementAccessFeedback const* processed =
     797             :       broker()->ProcessFeedbackMapsForElementAccess(
     798          32 :           GetRelevantReceiverMaps(broker()->isolate(), maps));
     799          16 :   broker()->SetFeedback(source, processed);
     800          16 :   if (processed == nullptr) return;
     801             : 
     802           0 :   for (ElementAccessFeedback::MapIterator it = processed->all_maps(broker());
     803           0 :        !it.done(); it.advance()) {
     804           0 :     switch (mode) {
     805             :       case AccessMode::kHas:
     806             :       case AccessMode::kLoad:
     807           0 :         it.current().SerializeForElementLoad();
     808           0 :         break;
     809             :       case AccessMode::kStore:
     810           0 :         it.current().SerializeForElementStore();
     811           0 :         break;
     812             :       case AccessMode::kStoreInLiteral:
     813             :         // This operation is fairly local and simple, nothing to serialize.
     814             :         break;
     815             :     }
     816             :   }
     817             : }
     818             : 
     819          16 : void SerializerForBackgroundCompilation::ProcessKeyedPropertyAccess(
     820             :     Hints const& receiver, Hints const& key, FeedbackSlot slot,
     821             :     AccessMode mode) {
     822          16 :   ProcessFeedbackForKeyedPropertyAccess(slot, mode);
     823             : 
     824          16 :   for (Handle<Object> hint : receiver.constants()) {
     825           0 :     ObjectRef receiver_ref(broker(), hint);
     826             : 
     827             :     // For JSNativeContextSpecialization::ReduceElementAccess.
     828           0 :     if (receiver_ref.IsJSTypedArray()) {
     829           0 :       receiver_ref.AsJSTypedArray().Serialize();
     830             :     }
     831             : 
     832             :     // For JSNativeContextSpecialization::ReduceKeyedLoadFromHeapConstant.
     833           0 :     if (mode == AccessMode::kLoad || mode == AccessMode::kHas) {
     834           0 :       for (Handle<Object> hint : key.constants()) {
     835           0 :         ObjectRef key_ref(broker(), hint);
     836             :         // TODO(neis): Do this for integer-HeapNumbers too?
     837           0 :         if (key_ref.IsSmi() && key_ref.AsSmi() >= 0) {
     838             :           base::Optional<ObjectRef> element =
     839           0 :               receiver_ref.GetOwnConstantElement(key_ref.AsSmi(), true);
     840           0 :           if (!element.has_value() && receiver_ref.IsJSArray()) {
     841             :             // We didn't find a constant element, but if the receiver is a
     842             :             // cow-array we can exploit the fact that any future write to the
     843             :             // element will replace the whole elements storage.
     844           0 :             receiver_ref.AsJSArray().GetOwnCowElement(key_ref.AsSmi(), true);
     845             :           }
     846             :         }
     847             :       }
     848             :     }
     849             :   }
     850             : 
     851          16 :   environment()->accumulator_hints().Clear();
     852          16 : }
     853             : 
     854           8 : void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
     855             :     MapRef const& map, NameRef const& name) {
     856             :   // For JSNativeContextSpecialization::ReduceNamedAccess.
     857           8 :   if (map.IsMapOfCurrentGlobalProxy()) {
     858           0 :     broker()->native_context().global_proxy_object().GetPropertyCell(name,
     859           0 :                                                                      true);
     860             :   }
     861           8 : }
     862             : 
     863             : // Note: We never use the same feedback slot for multiple names.
     864          17 : void SerializerForBackgroundCompilation::ProcessFeedbackForNamedPropertyAccess(
     865             :     FeedbackSlot slot, NameRef const& name) {
     866          25 :   if (slot.IsInvalid()) return;
     867          17 :   if (environment()->function().feedback_vector.is_null()) return;
     868             : 
     869             :   FeedbackNexus nexus(environment()->function().feedback_vector, slot);
     870          17 :   FeedbackSource source(nexus);
     871          17 :   if (broker()->HasFeedback(source)) return;
     872             : 
     873             :   MapHandles maps;
     874           9 :   nexus.ExtractMaps(&maps);
     875          26 :   for (Handle<Map> map : GetRelevantReceiverMaps(broker()->isolate(), maps)) {
     876           8 :     ProcessMapForNamedPropertyAccess(MapRef(broker(), map), name);
     877             :   }
     878             : 
     879             :   // NamedProperty support is still WIP. For now we don't have any actual data
     880             :   // to store, so use nullptr to at least record that we processed the feedback.
     881           9 :   broker()->SetFeedback(source, nullptr);
     882             : }
     883             : 
     884          16 : void SerializerForBackgroundCompilation::VisitLdaKeyedProperty(
     885             :     BytecodeArrayIterator* iterator) {
     886             :   Hints const& key = environment()->accumulator_hints();
     887             :   Hints const& receiver =
     888          16 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     889          16 :   FeedbackSlot slot = iterator->GetSlotOperand(1);
     890          16 :   ProcessKeyedPropertyAccess(receiver, key, slot, AccessMode::kLoad);
     891          16 : }
     892             : 
     893          17 : void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
     894             :     Hints const& receiver, NameRef const& name, FeedbackSlot slot,
     895             :     AccessMode mode) {
     896          17 :   if (!slot.IsInvalid()) ProcessFeedbackForNamedPropertyAccess(slot, name);
     897             : 
     898          17 :   for (Handle<Map> map :
     899          17 :        GetRelevantReceiverMaps(broker()->isolate(), receiver.maps())) {
     900           0 :     ProcessMapForNamedPropertyAccess(MapRef(broker(), map), name);
     901             :   }
     902             : 
     903             :   JSGlobalProxyRef global_proxy =
     904          17 :       broker()->native_context().global_proxy_object();
     905             : 
     906          17 :   for (Handle<Object> hint : receiver.constants()) {
     907           0 :     ObjectRef object(broker(), hint);
     908             :     // For JSNativeContextSpecialization::ReduceNamedAccessFromNexus.
     909           0 :     if (object.equals(global_proxy)) {
     910           0 :       global_proxy.GetPropertyCell(name, true);
     911             :     }
     912             :     // For JSNativeContextSpecialization::ReduceJSLoadNamed.
     913           0 :     if (mode == AccessMode::kLoad && object.IsJSFunction() &&
     914           0 :         name.equals(ObjectRef(
     915             :             broker(), broker()->isolate()->factory()->prototype_string()))) {
     916           0 :       object.AsJSFunction().Serialize();
     917             :     }
     918             :   }
     919             : 
     920          17 :   environment()->accumulator_hints().Clear();
     921          17 : }
     922             : 
     923          17 : void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
     924             :     BytecodeArrayIterator* iterator, AccessMode mode) {
     925             :   Hints const& receiver =
     926          17 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     927             :   Handle<Name> name(Name::cast(iterator->GetConstantForIndexOperand(1)),
     928          17 :                     broker()->isolate());
     929          17 :   FeedbackSlot slot = iterator->GetSlotOperand(2);
     930          17 :   ProcessNamedPropertyAccess(receiver, NameRef(broker(), name), slot, mode);
     931          17 : }
     932             : 
     933           0 : void SerializerForBackgroundCompilation::VisitLdaNamedProperty(
     934             :     BytecodeArrayIterator* iterator) {
     935          16 :   ProcessNamedPropertyAccess(iterator, AccessMode::kLoad);
     936           0 : }
     937             : 
     938           0 : void SerializerForBackgroundCompilation::VisitStaNamedProperty(
     939             :     BytecodeArrayIterator* iterator) {
     940           1 :   ProcessNamedPropertyAccess(iterator, AccessMode::kStore);
     941           0 : }
     942             : 
     943           0 : void SerializerForBackgroundCompilation::VisitTestIn(
     944             :     BytecodeArrayIterator* iterator) {
     945             :   Hints const& receiver = environment()->accumulator_hints();
     946             :   Hints const& key =
     947           0 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     948           0 :   FeedbackSlot slot = iterator->GetSlotOperand(1);
     949           0 :   ProcessKeyedPropertyAccess(receiver, key, slot, AccessMode::kHas);
     950           0 : }
     951             : 
     952           0 : void SerializerForBackgroundCompilation::VisitStaKeyedProperty(
     953             :     BytecodeArrayIterator* iterator) {
     954             :   Hints const& receiver =
     955           0 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     956             :   Hints const& key =
     957           0 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     958           0 :   FeedbackSlot slot = iterator->GetSlotOperand(2);
     959           0 :   ProcessKeyedPropertyAccess(receiver, key, slot, AccessMode::kStore);
     960           0 : }
     961             : 
     962           0 : void SerializerForBackgroundCompilation::VisitStaInArrayLiteral(
     963             :     BytecodeArrayIterator* iterator) {
     964             :   Hints const& receiver =
     965           0 :       environment()->register_hints(iterator->GetRegisterOperand(0));
     966             :   Hints const& key =
     967           0 :       environment()->register_hints(iterator->GetRegisterOperand(1));
     968           0 :   FeedbackSlot slot = iterator->GetSlotOperand(2);
     969           0 :   ProcessKeyedPropertyAccess(receiver, key, slot, AccessMode::kStoreInLiteral);
     970           0 : }
     971             : 
     972             : #define DEFINE_CLEAR_ENVIRONMENT(name, ...)             \
     973             :   void SerializerForBackgroundCompilation::Visit##name( \
     974             :       BytecodeArrayIterator* iterator) {                \
     975             :     environment()->ClearEphemeralHints();               \
     976             :   }
     977           0 : CLEAR_ENVIRONMENT_LIST(DEFINE_CLEAR_ENVIRONMENT)
     978             : #undef DEFINE_CLEAR_ENVIRONMENT
     979             : 
     980             : #define DEFINE_CLEAR_ACCUMULATOR(name, ...)             \
     981             :   void SerializerForBackgroundCompilation::Visit##name( \
     982             :       BytecodeArrayIterator* iterator) {                \
     983             :     environment()->accumulator_hints().Clear();         \
     984             :   }
     985         135 : CLEAR_ACCUMULATOR_LIST(DEFINE_CLEAR_ACCUMULATOR)
     986             : #undef DEFINE_CLEAR_ACCUMULATOR
     987             : 
     988             : #define DEFINE_CONDITIONAL_JUMP(name, ...)              \
     989             :   void SerializerForBackgroundCompilation::Visit##name( \
     990             :       BytecodeArrayIterator* iterator) {                \
     991             :     ProcessJump(iterator);                              \
     992             :   }
     993           0 : CONDITIONAL_JUMPS_LIST(DEFINE_CONDITIONAL_JUMP)
     994             : #undef DEFINE_CONDITIONAL_JUMP
     995             : 
     996             : #define DEFINE_UNCONDITIONAL_JUMP(name, ...)            \
     997             :   void SerializerForBackgroundCompilation::Visit##name( \
     998             :       BytecodeArrayIterator* iterator) {                \
     999             :     ProcessJump(iterator);                              \
    1000             :     environment()->ClearEphemeralHints();               \
    1001             :   }
    1002           6 : UNCONDITIONAL_JUMPS_LIST(DEFINE_UNCONDITIONAL_JUMP)
    1003             : #undef DEFINE_UNCONDITIONAL_JUMP
    1004             : 
    1005             : #define DEFINE_IGNORE(name, ...)                        \
    1006             :   void SerializerForBackgroundCompilation::Visit##name( \
    1007             :       BytecodeArrayIterator* iterator) {}
    1008           0 : IGNORED_BYTECODE_LIST(DEFINE_IGNORE)
    1009             : #undef DEFINE_IGNORE
    1010             : 
    1011             : }  // namespace compiler
    1012             : }  // namespace internal
    1013      121996 : }  // namespace v8

Generated by: LCOV version 1.10