LCOV - code coverage report
Current view: top level - src/parsing - preparsed-scope-data.h (source / functions) Hit Total Coverage
Test: app.info Lines: 2 2 100.0 %
Date: 2017-04-26 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright 2017 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             : #ifndef V8_PARSING_PREPARSED_SCOPE_DATA_H_
       6             : #define V8_PARSING_PREPARSED_SCOPE_DATA_H_
       7             : 
       8             : #include <set>
       9             : #include <unordered_map>
      10             : #include <vector>
      11             : 
      12             : #include "src/globals.h"
      13             : #include "src/objects.h"
      14             : #include "src/parsing/preparse-data.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : template <typename T>
      20             : class Handle;
      21             : 
      22             : /*
      23             : 
      24             :   Skipping inner functions.
      25             : 
      26             :   Consider the following code:
      27             :   (function eager_outer() {
      28             :     function lazy_inner() {
      29             :       let a;
      30             :       function skip_me() { a; }
      31             :     }
      32             : 
      33             :     return lazy_inner;
      34             :   })();
      35             : 
      36             :   ... lazy_inner(); ...
      37             : 
      38             :   When parsing the code the first time, eager_outer is parsed and lazy_inner
      39             :   (and everything inside it) is preparsed. When lazy_inner is called, we don't
      40             :   want to parse or preparse skip_me again. Instead, we want to skip over it,
      41             :   since it has already been preparsed once.
      42             : 
      43             :   In order to be able to do this, we need to store the information needed for
      44             :   allocating the variables in lazy_inner when we preparse it, and then later do
      45             :   scope allocation based on that data.
      46             : 
      47             :   We need the following data for each scope in lazy_inner's scope tree:
      48             :   For each Variable:
      49             :   - is_used
      50             :   - maybe_assigned
      51             :   - has_forced_context_allocation
      52             : 
      53             :   For each Scope:
      54             :   - inner_scope_calls_eval_.
      55             : 
      56             :   PreParsedScopeData implements storing and restoring the above mentioned data.
      57             : 
      58             :  */
      59             : 
      60             : class PreParsedScopeData {
      61             :  public:
      62    14526164 :   PreParsedScopeData() {}
      63     9684080 :   ~PreParsedScopeData() {}
      64             : 
      65             :   // Saves the information needed for allocating the Scope's (and its
      66             :   // subscopes') variables.
      67             :   void SaveData(Scope* scope);
      68             : 
      69             :   // Save data for a function we might skip later. The data is used later for
      70             :   // creating a FunctionLiteral.
      71             :   void AddSkippableFunction(int start_position,
      72             :                             const PreParseData::FunctionData& function_data);
      73             : 
      74             :   // Save variable allocation data for function which contains skippable
      75             :   // functions.
      76             :   void AddFunction(int start_position,
      77             :                    const PreParseData::FunctionData& function_data);
      78             : 
      79             :   // FIXME(marja): We need different kinds of data for the two types of
      80             :   // functions. For a skippable function we need the end position + the data
      81             :   // needed for creating a FunctionLiteral. For a function which contains
      82             :   // skippable functions, we need the data affecting context allocation status
      83             :   // of the variables (but e.g., no end position). Currently we just save the
      84             :   // same data for both. Here we can save less data.
      85             : 
      86             :   // Restores the information needed for allocating the Scopes's (and its
      87             :   // subscopes') variables.
      88             :   void RestoreData(Scope* scope, uint32_t* index_ptr) const;
      89             :   void RestoreData(DeclarationScope* scope) const;
      90             : 
      91             :   Handle<PodArray<uint32_t>> Serialize(Isolate* isolate) const;
      92             :   void Deserialize(PodArray<uint32_t>* array);
      93             : 
      94             :   bool Consuming() const { return has_data_; }
      95             : 
      96             :   bool Producing() const { return !has_data_; }
      97             : 
      98             :   PreParseData::FunctionData FindSkippableFunction(int start_pos) const;
      99             : 
     100             :  private:
     101             :   friend class ScopeTestHelper;
     102             : 
     103             :   void SaveDataForVariable(Variable* var);
     104             :   void RestoreDataForVariable(Variable* var, uint32_t* index_ptr) const;
     105             :   void SaveDataForInnerScopes(Scope* scope);
     106             :   void RestoreDataForInnerScopes(Scope* scope, uint32_t* index_ptr) const;
     107             :   bool FindFunctionData(int start_pos, uint32_t* index) const;
     108             : 
     109             :   static bool ScopeNeedsData(Scope* scope);
     110             :   static bool IsSkippedFunctionScope(Scope* scope);
     111             : 
     112             :   // TODO(marja): Make the backing store more efficient once we know exactly
     113             :   // what data is needed.
     114             :   std::vector<uint32_t> backing_store_;
     115             : 
     116             :   // Start pos -> FunctionData. Used for creating FunctionLiterals for skipped
     117             :   // functions (when they're actually skipped).
     118             :   PreParseData function_index_;
     119             :   // Start pos -> position in backing_store_.
     120             :   std::unordered_map<uint32_t, uint32_t> function_data_positions_;
     121             :   // Start positions of skippable functions.
     122             :   std::set<uint32_t> skippable_functions_;
     123             : 
     124             :   bool has_data_ = false;
     125             : 
     126             :   DISALLOW_COPY_AND_ASSIGN(PreParsedScopeData);
     127             : };
     128             : 
     129             : }  // namespace internal
     130             : }  // namespace v8
     131             : 
     132             : #endif  // V8_PARSING_PREPARSED_SCOPE_DATA_H_

Generated by: LCOV version 1.10