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-01-20 Functions: 20 20 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    27174350 :   bool IsEmpty() const { return literal_bytes_.length() == 0; }
      50   109897281 :   int length() const {
      51   164181376 :     return is_one_byte() ? literal_bytes_.length()
      52   164204647 :                          : literal_bytes_.length() / 2;
      53             :   }
      54             :   bool AsArrayIndex(uint32_t* index) const;
      55             :   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      595350 :   int byte_length() const { return literal_bytes_.length(); }
      63             :   const unsigned char* raw_data() const {
      64    55230964 :     return literal_bytes_.start();
      65             :   }
      66             : 
      67             :   // For storing AstRawStrings in a hash map.
      68             :   uint32_t hash_field() const { return hash_field_; }
      69   249811232 :   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             :     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   117538782 :         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             :     return &next_;
      98             :   }
      99             : 
     100             :   void set_string(Handle<String> string) {
     101             :     DCHECK(!string.is_null());
     102             :     DCHECK(!has_string_);
     103    31072134 :     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    12076907 :   AstConsString* AddString(Zone* zone, const AstRawString* s) {
     130     7692011 :     if (s->IsEmpty()) return this;
     131     4384896 :     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      374276 :       Segment* tmp = new (zone->New(sizeof(Segment))) Segment;
     135      374227 :       *tmp = segment_;
     136      374227 :       segment_.next = tmp;
     137             :     }
     138     4384847 :     segment_.string = s;
     139     4384847 :     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             :     return Handle<String>(string_);
     153             :   }
     154             : 
     155             :   std::forward_list<const AstRawString*> ToRawStrings() const;
     156             : 
     157             :  private:
     158             :   friend class AstValueFactory;
     159             : 
     160    10273612 :   AstConsString() : next_(nullptr), segment_({nullptr, nullptr}) {}
     161             : 
     162             :   AstConsString* next() const { return next_; }
     163             :   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     8470449 :   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       32246 :   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(constructor, "constructor")                 \
     206             :   F(default, "default")                         \
     207             :   F(done, "done")                               \
     208             :   F(dot, ".")                                   \
     209             :   F(dot_for, ".for")                            \
     210             :   F(dot_generator_object, ".generator_object")  \
     211             :   F(dot_iterator, ".iterator")                  \
     212             :   F(dot_promise, ".promise")                    \
     213             :   F(dot_result, ".result")                      \
     214             :   F(dot_switch_tag, ".switch_tag")              \
     215             :   F(dot_catch, ".catch")                        \
     216             :   F(empty, "")                                  \
     217             :   F(eval, "eval")                               \
     218             :   F(from, "from")                               \
     219             :   F(function, "function")                       \
     220             :   F(get, "get")                                 \
     221             :   F(get_space, "get ")                          \
     222             :   F(length, "length")                           \
     223             :   F(let, "let")                                 \
     224             :   F(meta, "meta")                               \
     225             :   F(name, "name")                               \
     226             :   F(native, "native")                           \
     227             :   F(new_target, ".new.target")                  \
     228             :   F(next, "next")                               \
     229             :   F(number, "number")                           \
     230             :   F(object, "object")                           \
     231             :   F(of, "of")                                   \
     232             :   F(private_constructor, "#constructor")        \
     233             :   F(proto, "__proto__")                         \
     234             :   F(prototype, "prototype")                     \
     235             :   F(return, "return")                           \
     236             :   F(set, "set")                                 \
     237             :   F(set_space, "set ")                          \
     238             :   F(star_default_star, "*default*")             \
     239             :   F(string, "string")                           \
     240             :   F(symbol, "symbol")                           \
     241             :   F(target, "target")                           \
     242             :   F(this, "this")                               \
     243             :   F(this_function, ".this_function")            \
     244             :   F(throw, "throw")                             \
     245             :   F(undefined, "undefined")                     \
     246             :   F(value, "value")
     247             : 
     248       62868 : class AstStringConstants final {
     249             :  public:
     250             :   AstStringConstants(Isolate* isolate, uint64_t hash_seed);
     251             : 
     252             : #define F(name, str) \
     253             :   const AstRawString* name##_string() const { return name##_string_; }
     254             :   AST_STRING_CONSTANTS(F)
     255             : #undef F
     256             : 
     257             :   uint64_t hash_seed() const { return hash_seed_; }
     258             :   const base::CustomMatcherHashMap* string_table() const {
     259             :     return &string_table_;
     260             :   }
     261             : 
     262             :  private:
     263             :   Zone zone_;
     264             :   base::CustomMatcherHashMap string_table_;
     265             :   uint64_t hash_seed_;
     266             : 
     267             : #define F(name, str) AstRawString* name##_string_;
     268             :   AST_STRING_CONSTANTS(F)
     269             : #undef F
     270             : 
     271             :   DISALLOW_COPY_AND_ASSIGN(AstStringConstants);
     272             : };
     273             : 
     274             : class AstValueFactory {
     275             :  public:
     276     2955957 :   AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
     277             :                   uint64_t hash_seed)
     278             :       : string_table_(string_constants->string_table()),
     279             :         strings_(nullptr),
     280             :         strings_end_(&strings_),
     281             :         cons_strings_(nullptr),
     282             :         cons_strings_end_(&cons_strings_),
     283             :         string_constants_(string_constants),
     284             :         empty_cons_string_(nullptr),
     285             :         zone_(zone),
     286     5911933 :         hash_seed_(hash_seed) {
     287             :     DCHECK_EQ(hash_seed, string_constants->hash_seed());
     288             :     std::fill(one_character_strings_,
     289             :               one_character_strings_ + arraysize(one_character_strings_),
     290     2955976 :               nullptr);
     291     2955976 :     empty_cons_string_ = NewConsString();
     292     2955979 :   }
     293             : 
     294             :   Zone* zone() const { return zone_; }
     295             : 
     296             :   const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
     297    99044574 :     return GetOneByteStringInternal(literal);
     298             :   }
     299       77952 :   const AstRawString* GetOneByteString(const char* string) {
     300             :     return GetOneByteString(Vector<const uint8_t>(
     301      155907 :         reinterpret_cast<const uint8_t*>(string), StrLength(string)));
     302             :   }
     303             :   const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
     304       77462 :     return GetTwoByteStringInternal(literal);
     305             :   }
     306             :   const AstRawString* GetString(Handle<String> literal);
     307             : 
     308             :   // Clones an AstRawString from another ast value factory, adding it to this
     309             :   // factory and returning the clone.
     310             :   const AstRawString* CloneFromOtherFactory(const AstRawString* raw_string);
     311             : 
     312             :   V8_EXPORT_PRIVATE AstConsString* NewConsString();
     313             :   V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str);
     314             :   V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str1,
     315             :                                                  const AstRawString* str2);
     316             : 
     317             :   V8_EXPORT_PRIVATE void Internalize(Isolate* isolate);
     318             : 
     319             : #define F(name, str)                           \
     320             :   const AstRawString* name##_string() const {  \
     321             :     return string_constants_->name##_string(); \
     322             :   }
     323   344926465 :   AST_STRING_CONSTANTS(F)
     324             : #undef F
     325             :   const AstConsString* empty_cons_string() const { return empty_cons_string_; }
     326             : 
     327             :  private:
     328             :   AstRawString* AddString(AstRawString* string) {
     329    31713756 :     *strings_end_ = string;
     330    31713756 :     strings_end_ = string->next_location();
     331             :     return string;
     332             :   }
     333             :   AstConsString* AddConsString(AstConsString* string) {
     334    10273612 :     *cons_strings_end_ = string;
     335    10273612 :     cons_strings_end_ = string->next_location();
     336             :     return string;
     337             :   }
     338             :   void ResetStrings() {
     339     3784935 :     strings_ = nullptr;
     340     3784935 :     strings_end_ = &strings_;
     341     3784935 :     cons_strings_ = nullptr;
     342     3784935 :     cons_strings_end_ = &cons_strings_;
     343             :   }
     344             :   V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal(
     345             :       Vector<const uint8_t> literal);
     346             :   AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
     347             :   AstRawString* GetString(uint32_t hash, bool is_one_byte,
     348             :                           Vector<const byte> literal_bytes);
     349             : 
     350             :   // All strings are copied here, one after another (no zeroes inbetween).
     351             :   base::CustomMatcherHashMap string_table_;
     352             : 
     353             :   // We need to keep track of strings_ in order since cons strings require their
     354             :   // members to be internalized first.
     355             :   AstRawString* strings_;
     356             :   AstRawString** strings_end_;
     357             :   AstConsString* cons_strings_;
     358             :   AstConsString** cons_strings_end_;
     359             : 
     360             :   // Holds constant string values which are shared across the isolate.
     361             :   const AstStringConstants* string_constants_;
     362             :   const AstConsString* empty_cons_string_;
     363             : 
     364             :   // Caches one character lowercase strings (for minified code).
     365             :   static const int kMaxOneCharStringValue = 128;
     366             :   AstRawString* one_character_strings_[kMaxOneCharStringValue];
     367             : 
     368             :   Zone* zone_;
     369             : 
     370             :   uint64_t hash_seed_;
     371             : };
     372             : }  // namespace internal
     373             : }  // namespace v8
     374             : 
     375             : #endif  // V8_AST_AST_VALUE_FACTORY_H_

Generated by: LCOV version 1.10