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