1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include <assert.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string> 33 #include <vector> 34 #include "src/v8.h" 35 36 #include "src/api.h" 37 #include "src/compiler.h" 38 #include "src/scanner-character-streams.h" 39 #include "tools/shell-utils.h" 40 #include "src/parser.h" 41 #include "src/preparse-data-format.h" 42 #include "src/preparse-data.h" 43 #include "src/preparser.h" 44 45 using namespace v8::internal; 46 47 std::pair<TimeDelta, TimeDelta> RunBaselineParser( 48 const char* fname, Encoding encoding, int repeat, v8::Isolate* isolate, 49 v8::Handle<v8::Context> context) { 50 int length = 0; 51 const byte* source = ReadFileAndRepeat(fname, &length, repeat); 52 v8::Handle<v8::String> source_handle; 53 switch (encoding) { 54 case UTF8: { 55 source_handle = v8::String::NewFromUtf8( 56 isolate, reinterpret_cast<const char*>(source)); 57 break; 58 } 59 case UTF16: { 60 source_handle = v8::String::NewFromTwoByte( 61 isolate, reinterpret_cast<const uint16_t*>(source), 62 v8::String::kNormalString, length / 2); 63 break; 64 } 65 case LATIN1: { 66 source_handle = v8::String::NewFromOneByte(isolate, source); 67 break; 68 } 69 } 70 TimeDelta parse_time1, parse_time2; 71 Handle<Script> script = Isolate::Current()->factory()->NewScript( 72 v8::Utils::OpenHandle(*source_handle)); 73 i::ScriptData* cached_data_impl = NULL; 74 // First round of parsing (produce data to cache). 75 { 76 CompilationInfoWithZone info(script); 77 info.MarkAsGlobal(); 78 info.SetCachedData(&cached_data_impl, i::PRODUCE_CACHED_DATA); 79 ElapsedTimer timer; 80 timer.Start(); 81 // Allow lazy parsing; otherwise we won't produce cached data. 82 bool success = Parser::Parse(&info, true); 83 parse_time1 = timer.Elapsed(); 84 if (!success) { 85 fprintf(stderr, "Parsing failed\n"); 86 return std::make_pair(TimeDelta(), TimeDelta()); 87 } 88 } 89 // Second round of parsing (consume cached data). 90 { 91 CompilationInfoWithZone info(script); 92 info.MarkAsGlobal(); 93 info.SetCachedData(&cached_data_impl, i::CONSUME_CACHED_DATA); 94 ElapsedTimer timer; 95 timer.Start(); 96 // Allow lazy parsing; otherwise cached data won't help. 97 bool success = Parser::Parse(&info, true); 98 parse_time2 = timer.Elapsed(); 99 if (!success) { 100 fprintf(stderr, "Parsing failed\n"); 101 return std::make_pair(TimeDelta(), TimeDelta()); 102 } 103 } 104 return std::make_pair(parse_time1, parse_time2); 105 } 106 107 108 int main(int argc, char* argv[]) { 109 v8::V8::InitializeICU(); 110 v8::V8::SetFlagsFromCommandLine(&argc, argv, true); 111 Encoding encoding = LATIN1; 112 std::vector<std::string> fnames; 113 std::string benchmark; 114 int repeat = 1; 115 for (int i = 0; i < argc; ++i) { 116 if (strcmp(argv[i], "--latin1") == 0) { 117 encoding = LATIN1; 118 } else if (strcmp(argv[i], "--utf8") == 0) { 119 encoding = UTF8; 120 } else if (strcmp(argv[i], "--utf16") == 0) { 121 encoding = UTF16; 122 } else if (strncmp(argv[i], "--benchmark=", 12) == 0) { 123 benchmark = std::string(argv[i]).substr(12); 124 } else if (strncmp(argv[i], "--repeat=", 9) == 0) { 125 std::string repeat_str = std::string(argv[i]).substr(9); 126 repeat = atoi(repeat_str.c_str()); 127 } else if (i > 0 && argv[i][0] != '-') { 128 fnames.push_back(std::string(argv[i])); 129 } 130 } 131 v8::Isolate* isolate = v8::Isolate::New(); 132 { 133 v8::Isolate::Scope isolate_scope(isolate); 134 v8::HandleScope handle_scope(isolate); 135 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); 136 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); 137 ASSERT(!context.IsEmpty()); 138 { 139 v8::Context::Scope scope(context); 140 double first_parse_total = 0; 141 double second_parse_total = 0; 142 for (size_t i = 0; i < fnames.size(); i++) { 143 std::pair<TimeDelta, TimeDelta> time = RunBaselineParser( 144 fnames[i].c_str(), encoding, repeat, isolate, context); 145 first_parse_total += time.first.InMillisecondsF(); 146 second_parse_total += time.second.InMillisecondsF(); 147 } 148 if (benchmark.empty()) benchmark = "Baseline"; 149 printf("%s(FirstParseRunTime): %.f ms\n", benchmark.c_str(), 150 first_parse_total); 151 printf("%s(SecondParseRunTime): %.f ms\n", benchmark.c_str(), 152 second_parse_total); 153 } 154 } 155 v8::V8::Dispose(); 156 return 0; 157 } 158