LCOV - code coverage report
Current view: top level - src/snapshot - natives-external.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 68 81 84.0 %
Date: 2017-10-20 Functions: 28 36 77.8 %

          Line data    Source code
       1             : // Copyright 2014 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/snapshot/natives.h"
       6             : 
       7             : #include "src/base/logging.h"
       8             : #include "src/snapshot/snapshot-source-sink.h"
       9             : #include "src/vector.h"
      10             : 
      11             : #ifndef V8_USE_EXTERNAL_STARTUP_DATA
      12             : #error natives-external.cc is used only for the external snapshot build.
      13             : #endif  // V8_USE_EXTERNAL_STARTUP_DATA
      14             : 
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : 
      20             : /**
      21             :  * NativesStore stores the 'native' (builtin) JS libraries.
      22             :  *
      23             :  * NativesStore needs to be initialized before using V8, usually by the
      24             :  * embedder calling v8::SetNativesDataBlob, which calls SetNativesFromFile
      25             :  * below.
      26             :  */
      27             : class NativesStore {
      28             :  public:
      29       88407 :   ~NativesStore() {
      30     1001946 :     for (size_t i = 0; i < native_names_.size(); i++) {
      31      500973 :       native_names_[i].Dispose();
      32             :     }
      33       88407 :   }
      34             : 
      35        1350 :   int GetBuiltinsCount() { return static_cast<int>(native_ids_.size()); }
      36             :   int GetDebuggerCount() { return debugger_count_; }
      37             : 
      38             :   Vector<const char> GetScriptSource(int index) {
      39     1125396 :     return native_source_[index];
      40             :   }
      41             : 
      42       26440 :   Vector<const char> GetScriptName(int index) { return native_names_[index]; }
      43             : 
      44           0 :   int GetIndex(const char* id) {
      45           0 :     for (int i = 0; i < static_cast<int>(native_ids_.size()); ++i) {
      46           0 :       int native_id_length = native_ids_[i].length();
      47           0 :       if ((static_cast<int>(strlen(id)) == native_id_length) &&
      48           0 :           (strncmp(id, native_ids_[i].start(), native_id_length) == 0)) {
      49           0 :         return i;
      50             :       }
      51             :     }
      52           0 :     UNREACHABLE();
      53             :   }
      54             : 
      55           0 :   Vector<const char> GetScriptsSource() {
      56           0 :     UNREACHABLE();  // Not implemented.
      57             :   }
      58             : 
      59      161979 :   static NativesStore* MakeFromScriptsSource(SnapshotByteSource* source) {
      60      161979 :     NativesStore* store = new NativesStore;
      61             : 
      62             :     // We expect the libraries in the following format:
      63             :     //   int: # of debugger sources.
      64             :     //   2N blobs: N pairs of source name + actual source.
      65             :     //   then, repeat for non-debugger sources.
      66      161979 :     int debugger_count = source->GetInt();
      67      323958 :     for (int i = 0; i < debugger_count; ++i)
      68      161979 :       store->ReadNameAndContentPair(source);
      69      161979 :     int library_count = source->GetInt();
      70      755902 :     for (int i = 0; i < library_count; ++i)
      71      593923 :       store->ReadNameAndContentPair(source);
      72             : 
      73      161979 :     store->debugger_count_ = debugger_count;
      74      161979 :     return store;
      75             :   }
      76             : 
      77             :  private:
      78      161979 :   NativesStore() : debugger_count_(0) {}
      79             : 
      80      755902 :   Vector<const char> NameFromId(const byte* id, int id_length) {
      81      755902 :     const char native[] = "native ";
      82      755902 :     const char extension[] = ".js";
      83             :     Vector<char> name(Vector<char>::New(id_length + sizeof(native) - 1 +
      84      755902 :                                         sizeof(extension) - 1));
      85             :     memcpy(name.start(), native, sizeof(native) - 1);
      86      755902 :     memcpy(name.start() + sizeof(native) - 1, id, id_length);
      87      755902 :     memcpy(name.start() + sizeof(native) - 1 + id_length, extension,
      88             :            sizeof(extension) - 1);
      89      755902 :     return Vector<const char>::cast(name);
      90             :   }
      91             : 
      92      755902 :   void ReadNameAndContentPair(SnapshotByteSource* bytes) {
      93             :     const byte* id;
      94             :     const byte* source;
      95      755902 :     int id_length = bytes->GetBlob(&id);
      96      755902 :     int source_length = bytes->GetBlob(&source);
      97      755902 :     native_ids_.emplace_back(reinterpret_cast<const char*>(id), id_length);
      98             :     native_source_.emplace_back(reinterpret_cast<const char*>(source),
      99      755902 :                                 source_length);
     100     1511804 :     native_names_.push_back(NameFromId(id, id_length));
     101      755902 :   }
     102             : 
     103             :   std::vector<Vector<const char>> native_ids_;
     104             :   std::vector<Vector<const char>> native_names_;
     105             :   std::vector<Vector<const char>> native_source_;
     106             :   int debugger_count_;
     107             : 
     108             :   DISALLOW_COPY_AND_ASSIGN(NativesStore);
     109             : };
     110             : 
     111             : 
     112             : template<NativeType type>
     113             : class NativesHolder {
     114             :  public:
     115      593259 :   static NativesStore* get() {
     116      593259 :     CHECK(holder_);
     117      593259 :     return holder_;
     118             :   }
     119      161979 :   static void set(NativesStore* store) {
     120      161979 :     CHECK(store);
     121      161979 :     holder_ = store;
     122      161979 :   }
     123       57811 :   static bool empty() { return holder_ == nullptr; }
     124       88497 :   static void Dispose() {
     125       88497 :     delete holder_;
     126       88497 :     holder_ = nullptr;
     127       88497 :   }
     128             : 
     129             :  private:
     130             :   static NativesStore* holder_;
     131             : };
     132             : 
     133             : template <NativeType type>
     134             : NativesStore* NativesHolder<type>::holder_ = nullptr;
     135             : 
     136             : // The natives blob. Memory is owned by caller.
     137             : static StartupData* natives_blob_ = nullptr;
     138             : 
     139             : /**
     140             :  * Read the Natives blob, as previously set by SetNativesFromFile.
     141             :  */
     142      108313 : void ReadNatives() {
     143      166124 :   if (natives_blob_ && NativesHolder<CORE>::empty()) {
     144       53993 :     SnapshotByteSource bytes(natives_blob_->data, natives_blob_->raw_size);
     145       53993 :     NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
     146       53993 :     NativesHolder<EXTRAS>::set(NativesStore::MakeFromScriptsSource(&bytes));
     147             :     NativesHolder<EXPERIMENTAL_EXTRAS>::set(
     148       53993 :         NativesStore::MakeFromScriptsSource(&bytes));
     149             :     DCHECK(!bytes.HasMore());
     150             :   }
     151      108313 : }
     152             : 
     153             : 
     154             : /**
     155             :  * Set the Natives (library sources) blob, as generated by js2c + the build
     156             :  * system.
     157             :  */
     158       53983 : void SetNativesFromFile(StartupData* natives_blob) {
     159             :   DCHECK(!natives_blob_);
     160             :   DCHECK(natives_blob);
     161             :   DCHECK(natives_blob->data);
     162             :   DCHECK_GT(natives_blob->raw_size, 0);
     163             : 
     164       53983 :   natives_blob_ = natives_blob;
     165       53983 :   ReadNatives();
     166       53983 : }
     167             : 
     168             : 
     169             : /**
     170             :  * Release memory allocated by SetNativesFromFile.
     171             :  */
     172       29499 : void DisposeNatives() {
     173       29499 :   NativesHolder<CORE>::Dispose();
     174       29499 :   NativesHolder<EXTRAS>::Dispose();
     175       29499 :   NativesHolder<EXPERIMENTAL_EXTRAS>::Dispose();
     176       29499 : }
     177             : 
     178             : 
     179             : // Implement NativesCollection<T> bsaed on NativesHolder + NativesStore.
     180             : //
     181             : // (The callers expect a purely static interface, since this is how the
     182             : //  natives are usually compiled in. Since we implement them based on
     183             : //  runtime content, we have to implement this indirection to offer
     184             : //  a static interface.)
     185             : template<NativeType type>
     186         675 : int NativesCollection<type>::GetBuiltinsCount() {
     187        1350 :   return NativesHolder<type>::get()->GetBuiltinsCount();
     188             : }
     189             : 
     190             : template<NativeType type>
     191       16666 : int NativesCollection<type>::GetDebuggerCount() {
     192       16666 :   return NativesHolder<type>::get()->GetDebuggerCount();
     193             : }
     194             : 
     195             : template<NativeType type>
     196           0 : int NativesCollection<type>::GetIndex(const char* name) {
     197           0 :   return NativesHolder<type>::get()->GetIndex(name);
     198             : }
     199             : 
     200             : template <NativeType type>
     201      562698 : Vector<const char> NativesCollection<type>::GetScriptSource(int index) {
     202     1125396 :   return NativesHolder<type>::get()->GetScriptSource(index);
     203             : }
     204             : 
     205             : template<NativeType type>
     206       13220 : Vector<const char> NativesCollection<type>::GetScriptName(int index) {
     207       26440 :   return NativesHolder<type>::get()->GetScriptName(index);
     208             : }
     209             : 
     210             : template <NativeType type>
     211           0 : Vector<const char> NativesCollection<type>::GetScriptsSource() {
     212           0 :   return NativesHolder<type>::get()->GetScriptsSource();
     213             : }
     214             : 
     215             : 
     216             : // Explicit template instantiations.
     217             : #define INSTANTIATE_TEMPLATES(T)                                            \
     218             :   template int NativesCollection<T>::GetBuiltinsCount();                    \
     219             :   template int NativesCollection<T>::GetDebuggerCount();                    \
     220             :   template int NativesCollection<T>::GetIndex(const char* name);            \
     221             :   template Vector<const char> NativesCollection<T>::GetScriptSource(int i); \
     222             :   template Vector<const char> NativesCollection<T>::GetScriptName(int i);   \
     223             :   template Vector<const char> NativesCollection<T>::GetScriptsSource();
     224             : INSTANTIATE_TEMPLATES(CORE)
     225             : INSTANTIATE_TEMPLATES(EXTRAS)
     226             : INSTANTIATE_TEMPLATES(EXPERIMENTAL_EXTRAS)
     227             : #undef INSTANTIATE_TEMPLATES
     228             : 
     229             : }  // namespace internal
     230             : }  // namespace v8

Generated by: LCOV version 1.10