Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(657)

Side by Side Diff: ppapi/native_client/src/trusted/plugin/json_manifest.cc

Issue 12623004: Allow PNaCl NMF to set translator optimization options for experimentation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Default to -O0 instead of the default for now Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "native_client/src/trusted/plugin/json_manifest.h" 9 #include "native_client/src/trusted/plugin/json_manifest.h"
10 10
11 #include <stdlib.h> 11 #include <stdlib.h>
12 12
13 #include "native_client/src/include/nacl_base.h" 13 #include "native_client/src/include/nacl_base.h"
14 #include "native_client/src/include/nacl_macros.h" 14 #include "native_client/src/include/nacl_macros.h"
15 #include "native_client/src/include/nacl_string.h" 15 #include "native_client/src/include/nacl_string.h"
16 #include "native_client/src/include/portability.h" 16 #include "native_client/src/include/portability.h"
17 #include "native_client/src/shared/platform/nacl_check.h" 17 #include "native_client/src/shared/platform/nacl_check.h"
18 #include "native_client/src/trusted/plugin/plugin_error.h" 18 #include "native_client/src/trusted/plugin/plugin_error.h"
19 #include "native_client/src/trusted/plugin/pnacl_options.h"
19 #include "native_client/src/trusted/plugin/utility.h" 20 #include "native_client/src/trusted/plugin/utility.h"
20 #include "ppapi/cpp/dev/url_util_dev.h" 21 #include "ppapi/cpp/dev/url_util_dev.h"
21 #include "ppapi/cpp/var.h" 22 #include "ppapi/cpp/var.h"
22 #include "third_party/jsoncpp/source/include/json/reader.h" 23 #include "third_party/jsoncpp/source/include/json/reader.h"
23 24
24 namespace plugin { 25 namespace plugin {
25 26
26 namespace { 27 namespace {
27 // Top-level section name keys 28 // Top-level section name keys
28 const char* const kProgramKey = "program"; 29 const char* const kProgramKey = "program";
29 const char* const kInterpreterKey = "interpreter"; 30 const char* const kInterpreterKey = "interpreter";
30 const char* const kFilesKey = "files"; 31 const char* const kFilesKey = "files";
31 32
32 // ISA Dictionary keys 33 // ISA Dictionary keys
33 const char* const kX8632Key = "x86-32"; 34 const char* const kX8632Key = "x86-32";
34 const char* const kX8664Key = "x86-64"; 35 const char* const kX8664Key = "x86-64";
35 const char* const kArmKey = "arm"; 36 const char* const kArmKey = "arm";
36 const char* const kPortableKey = "portable"; 37 const char* const kPortableKey = "portable";
37 38
38 // Url Resolution keys 39 // Url Resolution keys
39 const char* const kPnaclTranslateKey = "pnacl-translate"; 40 const char* const kPnaclTranslateKey = "pnacl-translate";
40 const char* const kUrlKey = "url"; 41 const char* const kUrlKey = "url";
41 42
42 // Cache support keys 43 // Pnacl keys
43 const char* const kCacheIdentityKey = "sha256"; 44 const char* const kCacheIdentityKey = "sha256";
45 const char* const kOptLevelKey = "-O";
46 const char* const kPnaclExperimentalFlags = "experimental_flags";
44 47
45 // Sample manifest file: 48 // Sample manifest file:
46 // { 49 // {
47 // "program": { 50 // "program": {
48 // "x86-32": {"url": "myprogram_x86-32.nexe"}, 51 // "x86-32": {"url": "myprogram_x86-32.nexe"},
49 // "x86-64": {"url": "myprogram_x86-64.nexe"}, 52 // "x86-64": {"url": "myprogram_x86-64.nexe"},
50 // "arm": {"url": "myprogram_arm.nexe"}, 53 // "arm": {"url": "myprogram_arm.nexe"},
51 // "portable": { 54 // "portable": {
52 // "pnacl-translate": { 55 // "pnacl-translate": {
53 // "url": "myprogram.pexe", 56 // "url": "myprogram.pexe",
54 // "sha256": "..." 57 // "sha256": "...",
58 // "-O": 0
55 // } 59 // }
56 // } 60 // }
57 // }, 61 // },
58 // "interpreter": { 62 // "interpreter": {
59 // "x86-32": {"url": "interpreter_x86-32.nexe"}, 63 // "x86-32": {"url": "interpreter_x86-32.nexe"},
60 // "x86-64": {"url": "interpreter_x86-64.nexe"}, 64 // "x86-64": {"url": "interpreter_x86-64.nexe"},
61 // "arm": {"url": "interpreter_arm.nexe"} 65 // "arm": {"url": "interpreter_arm.nexe"}
62 // }, 66 // },
63 // "files": { 67 // "files": {
64 // "foo.txt": { 68 // "foo.txt": {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 return false; 251 return false;
248 } 252 }
249 } 253 }
250 254
251 // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include 255 // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include
252 // micro-architectures that can resolve to multiple valid sandboxes. 256 // micro-architectures that can resolve to multiple valid sandboxes.
253 bool has_isa = dictionary.isMember(sandbox_isa); 257 bool has_isa = dictionary.isMember(sandbox_isa);
254 bool has_portable = dictionary.isMember(kPortableKey); 258 bool has_portable = dictionary.isMember(kPortableKey);
255 259
256 if (!has_isa && !has_portable) { 260 if (!has_isa && !has_portable) {
257 error_info->SetReport(ERROR_MANIFEST_PROGRAM_MISSING_ARCH, 261 error_info->SetReport(
258 nacl::string("manifest: no version of ") + parent_key+ 262 ERROR_MANIFEST_PROGRAM_MISSING_ARCH,
263 nacl::string("manifest: no version of ") + parent_key +
259 " given for current arch and no portable version found."); 264 " given for current arch and no portable version found.");
260 return false; 265 return false;
261 } 266 }
262 267
263 return true; 268 return true;
264 } 269 }
265 270
266 void GrabUrlAndCacheIdentity(const Json::Value& url_spec, 271 void GrabUrlAndPnaclOptions(const Json::Value& url_spec,
267 nacl::string* url, 272 nacl::string* url,
268 nacl::string* cache_identity) { 273 PnaclOptions* pnacl_options) {
269 *url = url_spec[kUrlKey].asString(); 274 *url = url_spec[kUrlKey].asString();
270 if (url_spec.isMember(kCacheIdentityKey)) { 275 if (url_spec.isMember(kCacheIdentityKey)) {
271 *cache_identity = url_spec[kCacheIdentityKey].asString(); 276 pnacl_options->set_bitcode_hash(url_spec[kCacheIdentityKey].asString());
277 }
278 if (url_spec.isMember(kOptLevelKey)) {
279 uint32_t opt_raw = url_spec[kOptLevelKey].asUInt();
280 // Clamp the opt value to fit into an int8_t.
281 if (opt_raw > 3)
282 opt_raw = 3;
283 pnacl_options->set_opt_level(static_cast<int8_t>(opt_raw));
284 }
285 if (url_spec.isMember(kPnaclExperimentalFlags)) {
286 pnacl_options->set_experimental_flags(
287 url_spec[kPnaclExperimentalFlags].asString());
272 } 288 }
273 } 289 }
274 290
275 bool GetURLFromISADictionary(const Json::Value& dictionary, 291 bool GetURLFromISADictionary(const Json::Value& dictionary,
276 const nacl::string& parent_key, 292 const nacl::string& parent_key,
277 const nacl::string& sandbox_isa, 293 const nacl::string& sandbox_isa,
278 bool prefer_portable, 294 bool prefer_portable,
279 nacl::string* url, 295 nacl::string* url,
280 nacl::string* cache_identity, 296 PnaclOptions* pnacl_options,
281 ErrorInfo* error_info, 297 ErrorInfo* error_info) {
282 bool* pnacl_translate) { 298 if (url == NULL || pnacl_options == NULL || error_info == NULL)
283 if (url == NULL || cache_identity == NULL ||
284 error_info == NULL || pnacl_translate == NULL)
285 return false; 299 return false;
286 300
287 if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa, error_info)) 301 if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa, error_info))
288 return false; 302 return false;
289 303
290 *url = ""; 304 *url = "";
291 *cache_identity = "";
292 *pnacl_translate = false;
293 305
294 // The call to IsValidISADictionary() above guarantees that either 306 // The call to IsValidISADictionary() above guarantees that either
295 // sandbox_isa or kPortableKey is present in the dictionary. 307 // sandbox_isa or kPortableKey is present in the dictionary.
296 bool has_portable = dictionary.isMember(kPortableKey); 308 bool has_portable = dictionary.isMember(kPortableKey);
297 bool has_isa = dictionary.isMember(sandbox_isa); 309 bool has_isa = dictionary.isMember(sandbox_isa);
298 nacl::string chosen_isa; 310 nacl::string chosen_isa;
299 if ((has_portable && prefer_portable) || !has_isa) { 311 if ((has_portable && prefer_portable) || !has_isa) {
300 chosen_isa = kPortableKey; 312 chosen_isa = kPortableKey;
301 } else { 313 } else {
302 chosen_isa = sandbox_isa; 314 chosen_isa = sandbox_isa;
303 } 315 }
304 const Json::Value& isa_spec = dictionary[chosen_isa]; 316 const Json::Value& isa_spec = dictionary[chosen_isa];
305 // Check if this requires a pnacl-translate, otherwise just grab the URL. 317 // Check if this requires a pnacl-translate, otherwise just grab the URL.
306 // We may have pnacl-translate for isa-specific bitcode for CPU tuning. 318 // We may have pnacl-translate for isa-specific bitcode for CPU tuning.
307 if (isa_spec.isMember(kPnaclTranslateKey)) { 319 if (isa_spec.isMember(kPnaclTranslateKey)) {
308 GrabUrlAndCacheIdentity(isa_spec[kPnaclTranslateKey], url, cache_identity); 320 GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options);
309 *pnacl_translate = true; 321 pnacl_options->set_translate(true);
310 } else { 322 } else {
311 GrabUrlAndCacheIdentity(isa_spec, url, cache_identity); 323 *url = isa_spec[kUrlKey].asString();
312 *pnacl_translate = false; 324 pnacl_options->set_translate(false);
313 } 325 }
314 326
315 return true; 327 return true;
316 } 328 }
317 329
318 bool GetKeyUrl(const Json::Value& dictionary, 330 bool GetKeyUrl(const Json::Value& dictionary,
319 const nacl::string& key, 331 const nacl::string& key,
320 const nacl::string& sandbox_isa, 332 const nacl::string& sandbox_isa,
321 const Manifest* manifest, 333 const Manifest* manifest,
322 bool prefer_portable, 334 bool prefer_portable,
323 nacl::string* full_url, 335 nacl::string* full_url,
324 nacl::string* cache_identity, 336 PnaclOptions* pnacl_options,
325 ErrorInfo* error_info, 337 ErrorInfo* error_info) {
326 bool* pnacl_translate) {
327 CHECK(full_url != NULL && error_info != NULL); 338 CHECK(full_url != NULL && error_info != NULL);
328 if (!dictionary.isMember(key)) { 339 if (!dictionary.isMember(key)) {
329 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, 340 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL,
330 "file key not found in manifest"); 341 "file key not found in manifest");
331 return false; 342 return false;
332 } 343 }
333 const Json::Value& isa_dict = dictionary[key]; 344 const Json::Value& isa_dict = dictionary[key];
334 nacl::string relative_url; 345 nacl::string relative_url;
335 if (!GetURLFromISADictionary(isa_dict, key, sandbox_isa, prefer_portable, 346 if (!GetURLFromISADictionary(isa_dict, key, sandbox_isa, prefer_portable,
336 &relative_url, cache_identity, 347 &relative_url, pnacl_options, error_info)) {
337 error_info, pnacl_translate)) {
338 return false; 348 return false;
339 } 349 }
340 return manifest->ResolveURL(relative_url, full_url, error_info); 350 return manifest->ResolveURL(relative_url, full_url, error_info);
341 } 351 }
342 352
343 } // namespace 353 } // namespace
344 354
345 bool JsonManifest::Init(const nacl::string& manifest_json, 355 bool JsonManifest::Init(const nacl::string& manifest_json,
346 ErrorInfo* error_info) { 356 ErrorInfo* error_info) {
347 if (error_info == NULL) { 357 if (error_info == NULL) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 "could not resolve url '" + relative_url + 458 "could not resolve url '" + relative_url +
449 "' relative to manifest base url '" + manifest_base_url_.c_str() + 459 "' relative to manifest base url '" + manifest_base_url_.c_str() +
450 "'."); 460 "'.");
451 return false; 461 return false;
452 } 462 }
453 *full_url = resolved_url.AsString(); 463 *full_url = resolved_url.AsString();
454 return true; 464 return true;
455 } 465 }
456 466
457 bool JsonManifest::GetProgramURL(nacl::string* full_url, 467 bool JsonManifest::GetProgramURL(nacl::string* full_url,
458 nacl::string* cache_identity, 468 PnaclOptions* pnacl_options,
459 ErrorInfo* error_info, 469 ErrorInfo* error_info) const {
460 bool* pnacl_translate) const { 470 if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
461 if (full_url == NULL || cache_identity == NULL ||
462 error_info == NULL || pnacl_translate == NULL)
463 return false; 471 return false;
464 472
465 Json::Value program = dictionary_[kProgramKey]; 473 Json::Value program = dictionary_[kProgramKey];
466 474
467 nacl::string nexe_url; 475 nacl::string nexe_url;
468 nacl::string error_string; 476 nacl::string error_string;
469 477
470 if (!GetURLFromISADictionary(program, 478 if (!GetURLFromISADictionary(program,
471 kProgramKey, 479 kProgramKey,
472 sandbox_isa_, 480 sandbox_isa_,
473 prefer_portable_, 481 prefer_portable_,
474 &nexe_url, 482 &nexe_url,
475 cache_identity, 483 pnacl_options,
476 error_info, 484 error_info)) {
477 pnacl_translate)) {
478 return false; 485 return false;
479 } 486 }
480 487
481 return ResolveURL(nexe_url, full_url, error_info); 488 return ResolveURL(nexe_url, full_url, error_info);
482 } 489 }
483 490
484 bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const { 491 bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const {
485 if (!dictionary_.isMember(kFilesKey)) { 492 if (!dictionary_.isMember(kFilesKey)) {
486 // trivial success: no keys when there is no "files" section. 493 // trivial success: no keys when there is no "files" section.
487 return true; 494 return true;
488 } 495 }
489 const Json::Value& files = dictionary_[kFilesKey]; 496 const Json::Value& files = dictionary_[kFilesKey];
490 CHECK(files.isObject()); 497 CHECK(files.isObject());
491 Json::Value::Members members = files.getMemberNames(); 498 Json::Value::Members members = files.getMemberNames();
492 for (size_t i = 0; i < members.size(); ++i) { 499 for (size_t i = 0; i < members.size(); ++i) {
493 keys->insert(members[i]); 500 keys->insert(members[i]);
494 } 501 }
495 return true; 502 return true;
496 } 503 }
497 504
498 bool JsonManifest::ResolveKey(const nacl::string& key, 505 bool JsonManifest::ResolveKey(const nacl::string& key,
499 nacl::string* full_url, 506 nacl::string* full_url,
500 nacl::string* cache_identity, 507 PnaclOptions* pnacl_options,
501 ErrorInfo* error_info, 508 ErrorInfo* error_info) const {
502 bool* pnacl_translate) const {
503 NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str()); 509 NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str());
504 // key must be one of kProgramKey or kFileKey '/' file-section-key 510 // key must be one of kProgramKey or kFileKey '/' file-section-key
505 511
506 if (full_url == NULL || cache_identity == NULL || 512 if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
507 error_info == NULL || pnacl_translate == NULL)
508 return false; 513 return false;
509 514
510 if (key == kProgramKey) { 515 if (key == kProgramKey) {
511 return GetKeyUrl(dictionary_, key, sandbox_isa_, this, prefer_portable_, 516 return GetKeyUrl(dictionary_, key, sandbox_isa_, this, prefer_portable_,
512 full_url, cache_identity, error_info, pnacl_translate); 517 full_url, pnacl_options, error_info);
513 } 518 }
514 nacl::string::const_iterator p = find(key.begin(), key.end(), '/'); 519 nacl::string::const_iterator p = find(key.begin(), key.end(), '/');
515 if (p == key.end()) { 520 if (p == key.end()) {
516 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, 521 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL,
517 nacl::string("ResolveKey: invalid key, no slash: ") 522 nacl::string("ResolveKey: invalid key, no slash: ")
518 + key); 523 + key);
519 return false; 524 return false;
520 } 525 }
521 526
522 // generalize to permit other sections? 527 // generalize to permit other sections?
(...skipping 14 matching lines...) Expand all
537 nacl::string("ResolveKey: no \"files\" dictionary")); 542 nacl::string("ResolveKey: no \"files\" dictionary"));
538 return false; 543 return false;
539 } 544 }
540 if (!files.isMember(rest)) { 545 if (!files.isMember(rest)) {
541 error_info->SetReport( 546 error_info->SetReport(
542 ERROR_MANIFEST_RESOLVE_URL, 547 ERROR_MANIFEST_RESOLVE_URL,
543 nacl::string("ResolveKey: no such \"files\" entry: ") + key); 548 nacl::string("ResolveKey: no such \"files\" entry: ") + key);
544 return false; 549 return false;
545 } 550 }
546 return GetKeyUrl(files, rest, sandbox_isa_, this, prefer_portable_, 551 return GetKeyUrl(files, rest, sandbox_isa_, this, prefer_portable_,
547 full_url, cache_identity, error_info, pnacl_translate); 552 full_url, pnacl_options, error_info);
548 } 553 }
549 554
550 } // namespace plugin 555 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/json_manifest.h ('k') | ppapi/native_client/src/trusted/plugin/manifest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698