LCOV - code coverage report
Current view: top level - src/snapshot - natives-external.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 70 79 88.6 %
Date: 2017-04-26 Functions: 28 35 80.0 %

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

Generated by: LCOV version 1.10