LCOV - code coverage report
Current view: top level - src - d8.h (source / functions) Hit Total Coverage
Test: app.info Lines: 24 50 48.0 %
Date: 2017-04-26 Functions: 5 13 38.5 %

          Line data    Source code
       1             : // Copyright 2012 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_D8_H_
       6             : #define V8_D8_H_
       7             : 
       8             : #include <iterator>
       9             : #include <memory>
      10             : #include <string>
      11             : #include <vector>
      12             : 
      13             : #include "src/allocation.h"
      14             : #include "src/base/hashmap.h"
      15             : #include "src/base/platform/time.h"
      16             : #include "src/list.h"
      17             : #include "src/utils.h"
      18             : 
      19             : #include "src/base/once.h"
      20             : 
      21             : 
      22             : namespace v8 {
      23             : 
      24             : 
      25             : // A single counter in a counter collection.
      26             : class Counter {
      27             :  public:
      28             :   static const int kMaxNameSize = 64;
      29             :   int32_t* Bind(const char* name, bool histogram);
      30             :   int32_t* ptr() { return &count_; }
      31             :   int32_t count() { return count_; }
      32             :   int32_t sample_total() { return sample_total_; }
      33             :   bool is_histogram() { return is_histogram_; }
      34             :   void AddSample(int32_t sample);
      35             :  private:
      36             :   int32_t count_;
      37             :   int32_t sample_total_;
      38             :   bool is_histogram_;
      39             :   uint8_t name_[kMaxNameSize];
      40             : };
      41             : 
      42             : 
      43             : // A set of counters and associated information.  An instance of this
      44             : // class is stored directly in the memory-mapped counters file if
      45             : // the --map-counters options is used
      46             : class CounterCollection {
      47             :  public:
      48             :   CounterCollection();
      49             :   Counter* GetNextCounter();
      50             :  private:
      51             :   static const unsigned kMaxCounters = 512;
      52             :   uint32_t magic_number_;
      53             :   uint32_t max_counters_;
      54             :   uint32_t max_name_size_;
      55             :   uint32_t counters_in_use_;
      56             :   Counter counters_[kMaxCounters];
      57             : };
      58             : 
      59             : 
      60             : class CounterMap {
      61             :  public:
      62             :   CounterMap(): hash_map_(Match) { }
      63           0 :   Counter* Lookup(const char* name) {
      64             :     base::HashMap::Entry* answer =
      65           0 :         hash_map_.Lookup(const_cast<char*>(name), Hash(name));
      66           0 :     if (!answer) return NULL;
      67           0 :     return reinterpret_cast<Counter*>(answer->value);
      68             :   }
      69           0 :   void Set(const char* name, Counter* value) {
      70             :     base::HashMap::Entry* answer =
      71           0 :         hash_map_.LookupOrInsert(const_cast<char*>(name), Hash(name));
      72             :     DCHECK(answer != NULL);
      73           0 :     answer->value = value;
      74           0 :   }
      75             :   class Iterator {
      76             :    public:
      77             :     explicit Iterator(CounterMap* map)
      78             :         : map_(&map->hash_map_), entry_(map_->Start()) { }
      79             :     void Next() { entry_ = map_->Next(entry_); }
      80             :     bool More() { return entry_ != NULL; }
      81           0 :     const char* CurrentKey() { return static_cast<const char*>(entry_->key); }
      82           0 :     Counter* CurrentValue() { return static_cast<Counter*>(entry_->value); }
      83             :    private:
      84             :     base::CustomMatcherHashMap* map_;
      85             :     base::CustomMatcherHashMap::Entry* entry_;
      86             :   };
      87             : 
      88             :  private:
      89             :   static int Hash(const char* name);
      90             :   static bool Match(void* key1, void* key2);
      91             :   base::CustomMatcherHashMap hash_map_;
      92             : };
      93             : 
      94             : 
      95             : class SourceGroup {
      96             :  public:
      97       28618 :   SourceGroup() :
      98             :       next_semaphore_(0),
      99             :       done_semaphore_(0),
     100             :       thread_(NULL),
     101             :       argv_(NULL),
     102             :       begin_offset_(0),
     103       28618 :       end_offset_(0) {}
     104             : 
     105             :   ~SourceGroup();
     106             : 
     107             :   void Begin(char** argv, int offset) {
     108       28618 :     argv_ = const_cast<const char**>(argv);
     109       28618 :     begin_offset_ = offset;
     110             :   }
     111             : 
     112       28618 :   void End(int offset) { end_offset_ = offset; }
     113             : 
     114             :   void Execute(Isolate* isolate);
     115             : 
     116             :   void StartExecuteInThread();
     117             :   void WaitForThread();
     118             :   void JoinThread();
     119             : 
     120             :  private:
     121           0 :   class IsolateThread : public base::Thread {
     122             :    public:
     123             :     explicit IsolateThread(SourceGroup* group)
     124           0 :         : base::Thread(GetThreadOptions()), group_(group) {}
     125             : 
     126           0 :     virtual void Run() {
     127           0 :       group_->ExecuteInThread();
     128           0 :     }
     129             : 
     130             :    private:
     131             :     SourceGroup* group_;
     132             :   };
     133             : 
     134             :   static base::Thread::Options GetThreadOptions();
     135             :   void ExecuteInThread();
     136             : 
     137             :   base::Semaphore next_semaphore_;
     138             :   base::Semaphore done_semaphore_;
     139             :   base::Thread* thread_;
     140             : 
     141             :   void ExitShell(int exit_code);
     142             :   Local<String> ReadFile(Isolate* isolate, const char* name);
     143             : 
     144             :   const char** argv_;
     145             :   int begin_offset_;
     146             :   int end_offset_;
     147             : };
     148             : 
     149             : // The backing store of an ArrayBuffer or SharedArrayBuffer, after
     150             : // Externalize() has been called on it.
     151             : class ExternalizedContents {
     152             :  public:
     153          60 :   explicit ExternalizedContents(const ArrayBuffer::Contents& contents)
     154          60 :       : data_(contents.Data()), size_(contents.ByteLength()) {}
     155         172 :   explicit ExternalizedContents(const SharedArrayBuffer::Contents& contents)
     156         172 :       : data_(contents.Data()), size_(contents.ByteLength()) {}
     157             :   ExternalizedContents(ExternalizedContents&& other)
     158         141 :       : data_(other.data_), size_(other.size_) {
     159         141 :     other.data_ = nullptr;
     160         141 :     other.size_ = 0;
     161             :   }
     162             :   ExternalizedContents& operator=(ExternalizedContents&& other) {
     163           0 :     if (this != &other) {
     164           0 :       data_ = other.data_;
     165           0 :       size_ = other.size_;
     166           0 :       other.data_ = nullptr;
     167           0 :       other.size_ = 0;
     168             :     }
     169             :     return *this;
     170             :   }
     171             :   ~ExternalizedContents();
     172             : 
     173             :  private:
     174             :   void* data_;
     175             :   size_t size_;
     176             : 
     177             :   DISALLOW_COPY_AND_ASSIGN(ExternalizedContents);
     178             : };
     179             : 
     180        2232 : class SerializationData {
     181             :  public:
     182        1116 :   SerializationData() : size_(0) {}
     183             : 
     184             :   uint8_t* data() { return data_.get(); }
     185             :   size_t size() { return size_; }
     186             :   const std::vector<ArrayBuffer::Contents>& array_buffer_contents() {
     187             :     return array_buffer_contents_;
     188             :   }
     189             :   const std::vector<SharedArrayBuffer::Contents>&
     190             :   shared_array_buffer_contents() {
     191             :     return shared_array_buffer_contents_;
     192             :   }
     193             : 
     194         861 :   void AppendExternalizedContentsTo(std::vector<ExternalizedContents>* to) {
     195             :     to->insert(to->end(),
     196             :                std::make_move_iterator(externalized_contents_.begin()),
     197         861 :                std::make_move_iterator(externalized_contents_.end()));
     198             :     externalized_contents_.clear();
     199         861 :   }
     200             : 
     201             :  private:
     202             :   struct DataDeleter {
     203         861 :     void operator()(uint8_t* p) const { free(p); }
     204             :   };
     205             : 
     206             :   std::unique_ptr<uint8_t, DataDeleter> data_;
     207             :   size_t size_;
     208             :   std::vector<ArrayBuffer::Contents> array_buffer_contents_;
     209             :   std::vector<SharedArrayBuffer::Contents> shared_array_buffer_contents_;
     210             :   std::vector<ExternalizedContents> externalized_contents_;
     211             : 
     212             :  private:
     213             :   friend class Serializer;
     214             : 
     215             :   DISALLOW_COPY_AND_ASSIGN(SerializationData);
     216             : };
     217             : 
     218             : 
     219        1581 : class SerializationDataQueue {
     220             :  public:
     221             :   void Enqueue(std::unique_ptr<SerializationData> data);
     222             :   bool Dequeue(std::unique_ptr<SerializationData>* data);
     223             :   bool IsEmpty();
     224             :   void Clear();
     225             : 
     226             :  private:
     227             :   base::Mutex mutex_;
     228             :   std::vector<std::unique_ptr<SerializationData>> data_;
     229             : };
     230             : 
     231             : 
     232             : class Worker {
     233             :  public:
     234             :   Worker();
     235             :   ~Worker();
     236             : 
     237             :   // Run the given script on this Worker. This function should only be called
     238             :   // once, and should only be called by the thread that created the Worker.
     239             :   void StartExecuteInThread(const char* script);
     240             :   // Post a message to the worker's incoming message queue. The worker will
     241             :   // take ownership of the SerializationData.
     242             :   // This function should only be called by the thread that created the Worker.
     243             :   void PostMessage(std::unique_ptr<SerializationData> data);
     244             :   // Synchronously retrieve messages from the worker's outgoing message queue.
     245             :   // If there is no message in the queue, block until a message is available.
     246             :   // If there are no messages in the queue and the worker is no longer running,
     247             :   // return nullptr.
     248             :   // This function should only be called by the thread that created the Worker.
     249             :   std::unique_ptr<SerializationData> GetMessage();
     250             :   // Terminate the worker's event loop. Messages from the worker that have been
     251             :   // queued can still be read via GetMessage().
     252             :   // This function can be called by any thread.
     253             :   void Terminate();
     254             :   // Terminate and join the thread.
     255             :   // This function can be called by any thread.
     256             :   void WaitForThread();
     257             : 
     258             :  private:
     259         527 :   class WorkerThread : public base::Thread {
     260             :    public:
     261             :     explicit WorkerThread(Worker* worker)
     262             :         : base::Thread(base::Thread::Options("WorkerThread")),
     263         527 :           worker_(worker) {}
     264             : 
     265         527 :     virtual void Run() { worker_->ExecuteInThread(); }
     266             : 
     267             :    private:
     268             :     Worker* worker_;
     269             :   };
     270             : 
     271             :   void ExecuteInThread();
     272             :   static void PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args);
     273             : 
     274             :   base::Semaphore in_semaphore_;
     275             :   base::Semaphore out_semaphore_;
     276             :   SerializationDataQueue in_queue_;
     277             :   SerializationDataQueue out_queue_;
     278             :   base::Thread* thread_;
     279             :   char* script_;
     280             :   base::Atomic32 running_;
     281             : };
     282             : 
     283             : class ShellOptions {
     284             :  public:
     285             :   ShellOptions()
     286             :       : script_executed(false),
     287             :         send_idle_notification(false),
     288             :         invoke_weak_callbacks(false),
     289             :         omit_quit(false),
     290             :         stress_opt(false),
     291             :         stress_deopt(false),
     292             :         stress_runs(1),
     293             :         interactive_shell(false),
     294             :         test_shell(false),
     295             :         expected_to_throw(false),
     296             :         mock_arraybuffer_allocator(false),
     297             :         enable_inspector(false),
     298             :         num_isolates(1),
     299             :         compile_options(v8::ScriptCompiler::kNoCompileOptions),
     300             :         isolate_sources(NULL),
     301             :         icu_data_file(NULL),
     302             :         natives_blob(NULL),
     303             :         snapshot_blob(NULL),
     304             :         trace_enabled(false),
     305             :         trace_config(NULL),
     306       28618 :         lcov_file(NULL) {}
     307             : 
     308           0 :   ~ShellOptions() {
     309           0 :     delete[] isolate_sources;
     310           0 :   }
     311             : 
     312             :   bool use_interactive_shell() {
     313       57236 :     return (interactive_shell || !script_executed) && !test_shell;
     314             :   }
     315             : 
     316             :   bool script_executed;
     317             :   bool send_idle_notification;
     318             :   bool invoke_weak_callbacks;
     319             :   bool omit_quit;
     320             :   bool stress_opt;
     321             :   bool stress_deopt;
     322             :   int stress_runs;
     323             :   bool interactive_shell;
     324             :   bool test_shell;
     325             :   bool expected_to_throw;
     326             :   bool mock_arraybuffer_allocator;
     327             :   bool enable_inspector;
     328             :   int num_isolates;
     329             :   v8::ScriptCompiler::CompileOptions compile_options;
     330             :   SourceGroup* isolate_sources;
     331             :   const char* icu_data_file;
     332             :   const char* natives_blob;
     333             :   const char* snapshot_blob;
     334             :   bool trace_enabled;
     335             :   const char* trace_config;
     336             :   const char* lcov_file;
     337             : };
     338             : 
     339             : class Shell : public i::AllStatic {
     340             :  public:
     341             :   static MaybeLocal<Script> CompileString(
     342             :       Isolate* isolate, Local<String> source, Local<Value> name,
     343             :       v8::ScriptCompiler::CompileOptions compile_options);
     344             :   static bool ExecuteString(Isolate* isolate, Local<String> source,
     345             :                             Local<Value> name, bool print_result,
     346             :                             bool report_exceptions);
     347             :   static bool ExecuteModule(Isolate* isolate, const char* file_name);
     348             :   static void ReportException(Isolate* isolate, TryCatch* try_catch);
     349             :   static Local<String> ReadFile(Isolate* isolate, const char* name);
     350             :   static Local<Context> CreateEvaluationContext(Isolate* isolate);
     351             :   static int RunMain(Isolate* isolate, int argc, char* argv[], bool last_run);
     352             :   static int Main(int argc, char* argv[]);
     353             :   static void Exit(int exit_code);
     354             :   static void OnExit(Isolate* isolate);
     355             :   static void CollectGarbage(Isolate* isolate);
     356             :   static void EmptyMessageQueues(Isolate* isolate);
     357             : 
     358             :   static std::unique_ptr<SerializationData> SerializeValue(
     359             :       Isolate* isolate, Local<Value> value, Local<Value> transfer);
     360             :   static MaybeLocal<Value> DeserializeValue(
     361             :       Isolate* isolate, std::unique_ptr<SerializationData> data);
     362             :   static void CleanupWorkers();
     363             :   static int* LookupCounter(const char* name);
     364             :   static void* CreateHistogram(const char* name,
     365             :                                int min,
     366             :                                int max,
     367             :                                size_t buckets);
     368             :   static void AddHistogramSample(void* histogram, int sample);
     369             :   static void MapCounters(v8::Isolate* isolate, const char* name);
     370             : 
     371             :   static void PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args);
     372             : 
     373             :   static void RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args);
     374             :   static void RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args);
     375             :   static void RealmGlobal(const v8::FunctionCallbackInfo<v8::Value>& args);
     376             :   static void RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args);
     377             :   static void RealmNavigate(const v8::FunctionCallbackInfo<v8::Value>& args);
     378             :   static void RealmCreateAllowCrossRealmAccess(
     379             :       const v8::FunctionCallbackInfo<v8::Value>& args);
     380             :   static void RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args);
     381             :   static void RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args);
     382             :   static void RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args);
     383             :   static void RealmSharedGet(Local<String> property,
     384             :                              const  PropertyCallbackInfo<Value>& info);
     385             :   static void RealmSharedSet(Local<String> property,
     386             :                              Local<Value> value,
     387             :                              const  PropertyCallbackInfo<void>& info);
     388             : 
     389             :   static void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
     390             :   static void PrintErr(const v8::FunctionCallbackInfo<v8::Value>& args);
     391             :   static void Write(const v8::FunctionCallbackInfo<v8::Value>& args);
     392             :   static void QuitOnce(v8::FunctionCallbackInfo<v8::Value>* args);
     393             :   static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args);
     394             :   static void Version(const v8::FunctionCallbackInfo<v8::Value>& args);
     395             :   static void Read(const v8::FunctionCallbackInfo<v8::Value>& args);
     396             :   static void ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
     397             :   static Local<String> ReadFromStdin(Isolate* isolate);
     398           0 :   static void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) {
     399           0 :     args.GetReturnValue().Set(ReadFromStdin(args.GetIsolate()));
     400           0 :   }
     401             :   static void Load(const v8::FunctionCallbackInfo<v8::Value>& args);
     402             :   static void WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args);
     403             :   static void WorkerPostMessage(
     404             :       const v8::FunctionCallbackInfo<v8::Value>& args);
     405             :   static void WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& args);
     406             :   static void WorkerTerminate(const v8::FunctionCallbackInfo<v8::Value>& args);
     407             :   // The OS object on the global object contains methods for performing
     408             :   // operating system calls:
     409             :   //
     410             :   // os.system("program_name", ["arg1", "arg2", ...], timeout1, timeout2) will
     411             :   // run the command, passing the arguments to the program.  The standard output
     412             :   // of the program will be picked up and returned as a multiline string.  If
     413             :   // timeout1 is present then it should be a number.  -1 indicates no timeout
     414             :   // and a positive number is used as a timeout in milliseconds that limits the
     415             :   // time spent waiting between receiving output characters from the program.
     416             :   // timeout2, if present, should be a number indicating the limit in
     417             :   // milliseconds on the total running time of the program.  Exceptions are
     418             :   // thrown on timeouts or other errors or if the exit status of the program
     419             :   // indicates an error.
     420             :   //
     421             :   // os.chdir(dir) changes directory to the given directory.  Throws an
     422             :   // exception/ on error.
     423             :   //
     424             :   // os.setenv(variable, value) sets an environment variable.  Repeated calls to
     425             :   // this method leak memory due to the API of setenv in the standard C library.
     426             :   //
     427             :   // os.umask(alue) calls the umask system call and returns the old umask.
     428             :   //
     429             :   // os.mkdirp(name, mask) creates a directory.  The mask (if present) is anded
     430             :   // with the current umask.  Intermediate directories are created if necessary.
     431             :   // An exception is not thrown if the directory already exists.  Analogous to
     432             :   // the "mkdir -p" command.
     433             :   static void System(const v8::FunctionCallbackInfo<v8::Value>& args);
     434             :   static void ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
     435             :   static void SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
     436             :   static void UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
     437             :   static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args);
     438             :   static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
     439             :   static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
     440             :   static void HostImportModuleDynamically(Isolate* isolate,
     441             :                                           Local<String> referrer,
     442             :                                           Local<String> specifier,
     443             :                                           Local<DynamicImportResult> result);
     444             : 
     445             :   // Data is of type DynamicImportData*. We use void* here to be able
     446             :   // to conform with MicrotaskCallback interface and enqueue this
     447             :   // function in the microtask queue.
     448             :   static void DoHostImportModuleDynamically(void* data);
     449             :   static void AddOSMethods(v8::Isolate* isolate,
     450             :                            Local<ObjectTemplate> os_template);
     451             : 
     452             :   static const char* kPrompt;
     453             :   static ShellOptions options;
     454             :   static ArrayBuffer::Allocator* array_buffer_allocator;
     455             : 
     456             :  private:
     457             :   static Global<Context> evaluation_context_;
     458             :   static base::OnceType quit_once_;
     459             :   static Global<Function> stringify_function_;
     460             :   static CounterMap* counter_map_;
     461             :   // We statically allocate a set of local counters to be used if we
     462             :   // don't want to store the stats in a memory-mapped file
     463             :   static CounterCollection local_counters_;
     464             :   static CounterCollection* counters_;
     465             :   static base::OS::MemoryMappedFile* counters_file_;
     466             :   static base::LazyMutex context_mutex_;
     467             :   static const base::TimeTicks kInitialTicks;
     468             : 
     469             :   static base::LazyMutex workers_mutex_;
     470             :   static bool allow_new_workers_;
     471             :   static i::List<Worker*> workers_;
     472             :   static std::vector<ExternalizedContents> externalized_contents_;
     473             : 
     474             :   static void WriteIgnitionDispatchCountersFile(v8::Isolate* isolate);
     475             :   // Append LCOV coverage data to file.
     476             :   static void WriteLcovData(v8::Isolate* isolate, const char* file);
     477             :   static Counter* GetCounter(const char* name, bool is_histogram);
     478             :   static Local<String> Stringify(Isolate* isolate, Local<Value> value);
     479             :   static void Initialize(Isolate* isolate);
     480             :   static void RunShell(Isolate* isolate);
     481             :   static bool SetOptions(int argc, char* argv[]);
     482             :   static Local<ObjectTemplate> CreateGlobalTemplate(Isolate* isolate);
     483             :   static MaybeLocal<Context> CreateRealm(
     484             :       const v8::FunctionCallbackInfo<v8::Value>& args, int index,
     485             :       v8::MaybeLocal<Value> global_object);
     486             :   static void DisposeRealm(const v8::FunctionCallbackInfo<v8::Value>& args,
     487             :                            int index);
     488             :   static MaybeLocal<Module> FetchModuleTree(v8::Local<v8::Context> context,
     489             :                                             const std::string& file_name);
     490             : };
     491             : 
     492             : 
     493             : }  // namespace v8
     494             : 
     495             : 
     496             : #endif  // V8_D8_H_

Generated by: LCOV version 1.10