LCOV - code coverage report
Current view: top level - src/ast - ast-value-factory.h (source / functions) Hit Total Coverage
Test: app.info Lines: 40 40 100.0 %
Date: 2019-04-17 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #ifndef V8_AST_AST_VALUE_FACTORY_H_
      29             : #define V8_AST_AST_VALUE_FACTORY_H_
      30             : 
      31             : #include <forward_list>
      32             : 
      33             : #include "src/base/hashmap.h"
      34             : #include "src/conversions.h"
      35             : #include "src/globals.h"
      36             : #include "src/heap/factory.h"
      37             : #include "src/isolate.h"
      38             : 
      39             : // Ast(Raw|Cons)String and AstValueFactory are for storing strings and
      40             : // values independent of the V8 heap and internalizing them later. During
      41             : // parsing, they are created and stored outside the heap, in AstValueFactory.
      42             : // After parsing, the strings and values are internalized (moved into the V8
      43             : // heap).
      44             : namespace v8 {
      45             : namespace internal {
      46             : 
      47             : class AstRawString final : public ZoneObject {
      48             :  public:
      49             :   bool IsEmpty() const { return literal_bytes_.length() == 0; }
      50             :   int length() const {
      51             :     return is_one_byte() ? literal_bytes_.length()
      52   152898517 :                          : literal_bytes_.length() / 2;
      53             :   }
      54             :   bool AsArrayIndex(uint32_t* index) const;
      55             :   V8_EXPORT_PRIVATE bool IsOneByteEqualTo(const char* data) const;
      56             :   uint16_t FirstCharacter() const;
      57             : 
      58             :   void Internalize(Isolate* isolate);
      59             : 
      60             :   // Access the physical representation:
      61             :   bool is_one_byte() const { return is_one_byte_; }
      62             :   int byte_length() const { return literal_bytes_.length(); }
      63             :   const unsigned char* raw_data() const {
      64             :     return literal_bytes_.start();
      65             :   }
      66             : 
      67             :   // For storing AstRawStrings in a hash map.
      68             :   uint32_t hash_field() const { return hash_field_; }
      69   228098913 :   uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }
      70             : 
      71             :   // This function can be called after internalizing.
      72             :   V8_INLINE Handle<String> string() const {
      73             :     DCHECK_NOT_NULL(string_);
      74             :     DCHECK(has_string_);
      75    28693104 :     return Handle<String>(string_);
      76             :   }
      77             : 
      78             :  private:
      79             :   friend class AstRawStringInternalizationKey;
      80             :   friend class AstStringConstants;
      81             :   friend class AstValueFactory;
      82             : 
      83             :   // Members accessed only by the AstValueFactory & related classes:
      84             :   static bool Compare(void* a, void* b);
      85             :   AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
      86             :                uint32_t hash_field)
      87             :       : next_(nullptr),
      88             :         literal_bytes_(literal_bytes),
      89             :         hash_field_(hash_field),
      90   109566428 :         is_one_byte_(is_one_byte) {}
      91             :   AstRawString* next() {
      92             :     DCHECK(!has_string_);
      93             :     return next_;
      94             :   }
      95             :   AstRawString** next_location() {
      96             :     DCHECK(!has_string_);
      97    29282224 :     return &next_;
      98             :   }
      99             : 
     100             :   void set_string(Handle<String> string) {
     101             :     DCHECK(!string.is_null());
     102             :     DCHECK(!has_string_);
     103    29486722 :     string_ = string.location();
     104             : #ifdef DEBUG
     105             :     has_string_ = true;
     106             : #endif
     107             :   }
     108             : 
     109             :   // {string_} is stored as Address* instead of a Handle<String> so it can be
     110             :   // stored in a union with {next_}.
     111             :   union {
     112             :     AstRawString* next_;
     113             :     Address* string_;
     114             :   };
     115             : 
     116             :   Vector<const byte> literal_bytes_;  // Memory owned by Zone.
     117             :   uint32_t hash_field_;
     118             :   bool is_one_byte_;
     119             : #ifdef DEBUG
     120             :   // (Debug-only:) Verify the object life-cylce: Some functions may only be
     121             :   // called after internalization (that is, after a v8::internal::String has
     122             :   // been set); some only before.
     123             :   bool has_string_ = false;
     124             : #endif
     125             : };
     126             : 
     127             : class AstConsString final : public ZoneObject {
     128             :  public:
     129     7822107 :   AstConsString* AddString(Zone* zone, const AstRawString* s) {
     130     7822107 :     if (s->IsEmpty()) return this;
     131     4533674 :     if (!IsEmpty()) {
     132             :       // We're putting the new string to the head of the list, meaning
     133             :       // the string segments will be in reverse order.
     134             :       Segment* tmp = new (zone->New(sizeof(Segment))) Segment;
     135      372661 :       *tmp = segment_;
     136      372661 :       segment_.next = tmp;
     137             :     }
     138     4533682 :     segment_.string = s;
     139     4533682 :     return this;
     140             :   }
     141             : 
     142             :   bool IsEmpty() const {
     143             :     DCHECK_IMPLIES(segment_.string == nullptr, segment_.next == nullptr);
     144             :     DCHECK_IMPLIES(segment_.string != nullptr, !segment_.string->IsEmpty());
     145             :     return segment_.string == nullptr;
     146             :   }
     147             : 
     148             :   void Internalize(Isolate* isolate);
     149             : 
     150             :   V8_INLINE Handle<String> string() const {
     151             :     DCHECK_NOT_NULL(string_);
     152     5739253 :     return Handle<String>(string_);
     153             :   }
     154             : 
     155             :   std::forward_list<const AstRawString*> ToRawStrings() const;
     156             : 
     157             :  private:
     158             :   friend class AstValueFactory;
     159             : 
     160    10444825 :   AstConsString() : next_(nullptr), segment_({nullptr, nullptr}) {}
     161             : 
     162             :   AstConsString* next() const { return next_; }
     163    10444825 :   AstConsString** next_location() { return &next_; }
     164             : 
     165             :   // {string_} is stored as Address* instead of a Handle<String> so it can be
     166             :   // stored in a union with {next_}.
     167     8590940 :   void set_string(Handle<String> string) { string_ = string.location(); }
     168             :   union {
     169             :     AstConsString* next_;
     170             :     Address* string_;
     171             :   };
     172             : 
     173             :   struct Segment {
     174             :     const AstRawString* string;
     175             :     AstConsString::Segment* next;
     176             :   };
     177             :   Segment segment_;
     178             : };
     179             : 
     180             : enum class AstSymbol : uint8_t { kHomeObjectSymbol };
     181             : 
     182             : class AstBigInt {
     183             :  public:
     184             :   // |bigint| must be a NUL-terminated string of ASCII characters
     185             :   // representing a BigInt (suitable for passing to BigIntLiteral()
     186             :   // from conversions.h).
     187          10 :   explicit AstBigInt(const char* bigint) : bigint_(bigint) {}
     188             : 
     189       32383 :   const char* c_str() const { return bigint_; }
     190             : 
     191             :  private:
     192             :   const char* bigint_;
     193             : };
     194             : 
     195             : // For generating constants.
     196             : #define AST_STRING_CONSTANTS(F)                 \
     197             :   F(anonymous, "anonymous")                     \
     198             :   F(anonymous_function, "(anonymous function)") \
     199             :   F(arguments, "arguments")                     \
     200             :   F(as, "as")                                   \
     201             :   F(async, "async")                             \
     202             :   F(await, "await")                             \
     203             :   F(bigint, "bigint")                           \
     204             :   F(boolean, "boolean")                         \
     205             :   F(computed, "<computed>")                     \
     206             :   F(constructor, "constructor")                 \
     207             :   F(default, "default")                         \
     208             :   F(done, "done")                               \
     209             :   F(dot, ".")                                   \
     210             :   F(dot_default, ".default")                    \
     211             :   F(dot_for, ".for")                            \
     212             :   F(dot_generator_object, ".generator_object")  \
     213             :   F(dot_iterator, ".iterator")                  \
     214             :   F(dot_promise, ".promise")                    \
     215             :   F(dot_result, ".result")                      \
     216             :   F(dot_switch_tag, ".switch_tag")              \
     217             :   F(dot_catch, ".catch")                        \
     218             :   F(empty, "")                                  \
     219             :   F(eval, "eval")                               \
     220             :   F(from, "from")                               \
     221             :   F(function, "function")                       \
     222             :   F(get, "get")                                 \
     223             :   F(get_space, "get ")                          \
     224             :   F(length, "length")                           \
     225             :   F(let, "let")                                 \
     226             :   F(meta, "meta")                               \
     227             :   F(name, "name")                               \
     228             :   F(native, "native")                           \
     229             :   F(new_target, ".new.target")                  \
     230             :   F(next, "next")                               \
     231             :   F(number, "number")                           \
     232             :   F(object, "object")                           \
     233             :   F(of, "of")                                   \
     234             :   F(private_constructor, "#constructor")        \
     235             :   F(proto, "__proto__")                         \
     236             :   F(prototype, "prototype")                     \
     237             :   F(return, "return")                           \
     238             :   F(set, "set")                                 \
     239             :   F(set_space, "set ")                          \
     240             :   F(string, "string")                           \
     241             :   F(symbol, "symbol")                           \
     242             :   F(target, "target")                           \
     243             :   F(this, "this")                               \
     244             :   F(this_function, ".this_function")            \
     245             :   F(throw, "throw")                             \
     246             :   F(undefined, "undefined")                     \
     247             :   F(value, "value")
     248             : 
     249       62407 : class AstStringConstants final {
     250             :  public:
     251             :   AstStringConstants(Isolate* isolate, uint64_t hash_seed);
     252             : 
     253             : #define F(name, str) \
     254             :   const AstRawString* name##_string() const { return name##_string_; }
     255             :   AST_STRING_CONSTANTS(F)
     256             : #undef F
     257             : 
     258             :   uint64_t hash_seed() const { return hash_seed_; }
     259             :   const base::CustomMatcherHashMap* string_table() const {
     260     2995455 :     return &string_table_;
     261             :   }
     262             : 
     263             :  private:
     264             :   Zone zone_;
     265             :   base::CustomMatcherHashMap string_table_;
     266             :   uint64_t hash_seed_;
     267             : 
     268             : #define F(name, str) AstRawString* name##_string_;
     269             :   AST_STRING_CONSTANTS(F)
     270             : #undef F
     271             : 
     272             :   DISALLOW_COPY_AND_ASSIGN(AstStringConstants);
     273             : };
     274             : 
     275     2995434 : class AstValueFactory {
     276             :  public:
     277     2995455 :   AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
     278             :                   uint64_t hash_seed)
     279             :       : string_table_(string_constants->string_table()),
     280             :         strings_(nullptr),
     281             :         strings_end_(&strings_),
     282             :         cons_strings_(nullptr),
     283             :         cons_strings_end_(&cons_strings_),
     284             :         string_constants_(string_constants),
     285             :         empty_cons_string_(nullptr),
     286             :         zone_(zone),
     287     2995443 :         hash_seed_(hash_seed) {
     288             :     DCHECK_EQ(hash_seed, string_constants->hash_seed());
     289     2995443 :     std::fill(one_character_strings_,
     290             :               one_character_strings_ + arraysize(one_character_strings_),
     291             :               nullptr);
     292     2995443 :     empty_cons_string_ = NewConsString();
     293     2995455 :   }
     294             : 
     295             :   Zone* zone() const { return zone_; }
     296             : 
     297             :   const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
     298    91361643 :     return GetOneByteStringInternal(literal);
     299             :   }
     300       78167 :   const AstRawString* GetOneByteString(const char* string) {
     301       78167 :     return GetOneByteString(Vector<const uint8_t>(
     302       78167 :         reinterpret_cast<const uint8_t*>(string), StrLength(string)));
     303             :   }
     304             :   const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
     305       77419 :     return GetTwoByteStringInternal(literal);
     306             :   }
     307             :   const AstRawString* GetString(Handle<String> literal);
     308             : 
     309             :   // Clones an AstRawString from another ast value factory, adding it to this
     310             :   // factory and returning the clone.
     311             :   const AstRawString* CloneFromOtherFactory(const AstRawString* raw_string);
     312             : 
     313             :   V8_EXPORT_PRIVATE AstConsString* NewConsString();
     314             :   V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str);
     315             :   V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str1,
     316             :                                                  const AstRawString* str2);
     317             : 
     318             :   V8_EXPORT_PRIVATE void Internalize(Isolate* isolate);
     319             : 
     320             : #define F(name, str)                           \
     321             :   const AstRawString* name##_string() const {  \
     322             :     return string_constants_->name##_string(); \
     323             :   }
     324             :   AST_STRING_CONSTANTS(F)
     325             : #undef F
     326             :   const AstConsString* empty_cons_string() const { return empty_cons_string_; }
     327             : 
     328             :  private:
     329             :   AstRawString* AddString(AstRawString* string) {
     330    29282224 :     *strings_end_ = string;
     331    29282224 :     strings_end_ = string->next_location();
     332             :     return string;
     333             :   }
     334             :   AstConsString* AddConsString(AstConsString* string) {
     335    10444825 :     *cons_strings_end_ = string;
     336    10444825 :     cons_strings_end_ = string->next_location();
     337             :     return string;
     338             :   }
     339             :   void ResetStrings() {
     340     3820832 :     strings_ = nullptr;
     341     3820832 :     strings_end_ = &strings_;
     342     3820832 :     cons_strings_ = nullptr;
     343     3820832 :     cons_strings_end_ = &cons_strings_;
     344             :   }
     345             :   V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal(
     346             :       Vector<const uint8_t> literal);
     347             :   AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
     348             :   AstRawString* GetString(uint32_t hash, bool is_one_byte,
     349             :                           Vector<const byte> literal_bytes);
     350             : 
     351             :   // All strings are copied here, one after another (no zeroes inbetween).
     352             :   base::CustomMatcherHashMap string_table_;
     353             : 
     354             :   // We need to keep track of strings_ in order since cons strings require their
     355             :   // members to be internalized first.
     356             :   AstRawString* strings_;
     357             :   AstRawString** strings_end_;
     358             :   AstConsString* cons_strings_;
     359             :   AstConsString** cons_strings_end_;
     360             : 
     361             :   // Holds constant string values which are shared across the isolate.
     362             :   const AstStringConstants* string_constants_;
     363             :   const AstConsString* empty_cons_string_;
     364             : 
     365             :   // Caches one character lowercase strings (for minified code).
     366             :   static const int kMaxOneCharStringValue = 128;
     367             :   AstRawString* one_character_strings_[kMaxOneCharStringValue];
     368             : 
     369             :   Zone* zone_;
     370             : 
     371             :   uint64_t hash_seed_;
     372             : };
     373             : }  // namespace internal
     374             : }  // namespace v8
     375             : 
     376             : #endif  // V8_AST_AST_VALUE_FACTORY_H_

Generated by: LCOV version 1.10