• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 COMPONENTS_NACL_RENDERER_PLUGIN_PNACL_COORDINATOR_H_
6 #define COMPONENTS_NACL_RENDERER_PLUGIN_PNACL_COORDINATOR_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <vector>
13 
14 #include "base/files/file.h"
15 #include "base/time/time.h"
16 #include "components/nacl/renderer/plugin/nacl_subprocess.h"
17 #include "components/nacl/renderer/plugin/plugin_error.h"
18 #include "components/nacl/renderer/plugin/pnacl_resources.h"
19 #include "ppapi/cpp/completion_callback.h"
20 #include "ppapi/utility/completion_callback_factory.h"
21 
22 struct PP_PNaClOptions;
23 
24 namespace plugin {
25 
26 class Plugin;
27 class PnaclCoordinator;
28 class PnaclTranslateThread;
29 
30 // A class invoked by Plugin to handle PNaCl client-side translation.
31 // Usage:
32 // (1) Invoke the factory method, e.g.,
33 //     PnaclCoordinator* coord = BitcodeToNative(plugin,
34 //                                               "http://foo.com/my.pexe",
35 //                                               pnacl_options,
36 //                                               translate_notify_callback);
37 // (2) translate_notify_callback gets invoked when translation is complete.
38 //     If the translation was successful, the pp_error argument is PP_OK.
39 //     Other values indicate errors.
40 // (3) After finish_callback runs, get the file descriptor of the translated
41 //     nexe, e.g.,
42 //     fd = coord->TakeTranslatedFileHandle();
43 // (4) Load the nexe from "fd".
44 // (5) delete coord.
45 //
46 // Translation proceeds in two steps:
47 // (1) llc translates the bitcode in pexe_url_ to an object in obj_file_.
48 // (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_.
49 class PnaclCoordinator {
50  public:
51   PnaclCoordinator(const PnaclCoordinator&) = delete;
52   PnaclCoordinator& operator=(const PnaclCoordinator&) = delete;
53 
54   virtual ~PnaclCoordinator();
55 
56   // The factory method for translations.
57   static PnaclCoordinator* BitcodeToNative(
58       Plugin* plugin,
59       const std::string& pexe_url,
60       const PP_PNaClOptions& pnacl_options,
61       const pp::CompletionCallback& translate_notify_callback);
62 
63   // Call this to take ownership of the FD of the translated nexe after
64   // BitcodeToNative has completed (and the finish_callback called).
65   PP_FileHandle TakeTranslatedFileHandle();
66 
67   // Return a callback that should be notified when |bytes_compiled| bytes
68   // have been compiled.
69   pp::CompletionCallback GetCompileProgressCallback(int64_t bytes_compiled);
70 
71   // Return true if we should delay the progress event reporting.
72   // This delay approximates:
73   // - the size of the buffer of bytes sent but not-yet-compiled by LLC.
74   // - the linking time.
ShouldDelayProgressEvent()75   bool ShouldDelayProgressEvent() {
76     const uint32_t kProgressEventSlopPct = 5;
77     return ((expected_pexe_size_ - pexe_bytes_compiled_) * 100 /
78             expected_pexe_size_) < kProgressEventSlopPct;
79   }
80 
81 
82   void BitcodeStreamCacheHit(PP_FileHandle handle);
83   void BitcodeStreamCacheMiss(int64_t expected_pexe_size,
84                               PP_FileHandle handle);
85 
86   // Invoked when a pexe data chunk arrives (when using streaming translation)
87   void BitcodeStreamGotData(const void* data, int32_t length);
88 
89   // Invoked when the pexe download finishes (using streaming translation)
90   void BitcodeStreamDidFinish(int32_t pp_error);
91 
92  private:
93   // BitcodeToNative is the factory method for PnaclCoordinators.
94   // Therefore the constructor is private.
95   PnaclCoordinator(Plugin* plugin,
96                    const std::string& pexe_url,
97                    const PP_PNaClOptions& pnacl_options,
98                    const pp::CompletionCallback& translate_notify_callback);
99 
100   // Invoke to issue a GET request for bitcode.
101   void OpenBitcodeStream();
102 
103   // Invoked when a pexe data chunk is compiled.
104   void BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled);
105   // Once llc and ld nexes have been loaded and the two temporary files have
106   // been created, this starts the translation.  Translation starts two
107   // subprocesses, one for llc and one for ld.
108   void LoadCompiler();
109   void RunCompile(int32_t pp_error, base::TimeTicks compile_load_start_time);
110   void LoadLinker(int32_t pp_error);
111   void RunLink(int32_t pp_error, base::TimeTicks ld_load_start_time);
112 
113   // Invoked when translation is finished.
114   void TranslateFinished(int32_t pp_error);
115 
116   // Invoked when the read descriptor for nexe_file_ is created.
117   void NexeReadDidOpen();
118 
119   // Bring control back to the plugin by invoking the
120   // |translate_notify_callback_|.  This does not set the ErrorInfo report,
121   // it is assumed that it was already set.
122   void ExitWithError();
123   // Run |translate_notify_callback_| with an error condition that is not
124   // PPAPI specific.  Also set ErrorInfo report.
125   void ReportNonPpapiError(PP_NaClError err, const std::string& message);
126 
127   // Keeps track of the pp_error upon entry to TranslateFinished,
128   // for inspection after cleanup.
129   int32_t translate_finish_error_;
130 
131   // The plugin owning the nexe for which we are doing translation.
132   Plugin* plugin_;
133 
134   pp::CompletionCallback translate_notify_callback_;
135   // Set to true when the translation (if applicable) is finished and the nexe
136   // file is loaded, (or when there was an error), and the browser has been
137   // notified via ReportTranslationFinished. If it is not set before
138   // plugin/coordinator destruction, the destructor will call
139   // ReportTranslationFinished.
140   bool translation_finished_reported_;
141   // Threadsafety is required to support file lookups.
142   pp::CompletionCallbackFactory<PnaclCoordinator,
143                                 pp::ThreadSafeThreadTraits> callback_factory_;
144 
145   // An auxiliary class that manages downloaded resources (llc and ld nexes).
146   std::unique_ptr<PnaclResources> resources_;
147   NaClSubprocess compiler_subprocess_;
148   NaClSubprocess ld_subprocess_;
149 
150   // The URL for the pexe file.
151   std::string pexe_url_;
152   // Options for translation.
153   PP_PNaClOptions pnacl_options_;
154   // Architecture-specific attributes used for translation. These are
155   // supplied by Chrome, not the developer, and are therefore different
156   // from PNaCl options.
157   std::string architecture_attributes_;
158 
159   // Object file, produced by the translator and consumed by the linker.
160   std::vector<base::File> obj_files_;
161   // Number of split modules for llc.
162   int split_module_count_;
163   // Number of threads for llc / subzero.
164   int num_threads_;
165 
166   // Translated nexe file, produced by the linker.
167   base::File temp_nexe_file_;
168 
169   // Used to report information when errors (PPAPI or otherwise) are reported.
170   ErrorInfo error_info_;
171 
172   // True if an error was already reported, and translate_notify_callback_
173   // was already run/consumed.
174   bool error_already_reported_;
175 
176   // State for timing and size information for UMA stats.
177   int64_t pexe_size_;  // Count as we stream -- will converge to pexe size.
178   int64_t pexe_bytes_compiled_;  // Count as we compile.
179   int64_t expected_pexe_size_;   // Expected download total (-1 if unknown).
180 
181   // The helper thread used to do translations via SRPC.
182   // It accesses fields of PnaclCoordinator so it must have a
183   // shorter lifetime.
184   std::unique_ptr<PnaclTranslateThread> translate_thread_;
185 };
186 
187 //----------------------------------------------------------------------
188 
189 }  // namespace plugin;
190 #endif  // COMPONENTS_NACL_RENDERER_PLUGIN_PNACL_COORDINATOR_H_
191