• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/libplatform/libplatform.h"
37 #include "src/api.h"
38 #include "src/compiler.h"
39 #include "src/parsing/parse-info.h"
40 #include "src/parsing/parser.h"
41 #include "src/parsing/preparse-data-format.h"
42 #include "src/parsing/preparse-data.h"
43 #include "src/parsing/preparser.h"
44 #include "src/parsing/scanner-character-streams.h"
45 #include "tools/shell-utils.h"
46 
47 using namespace v8::internal;
48 
49 class StringResource8 : public v8::String::ExternalOneByteStringResource {
50  public:
StringResource8(const char * data,int length)51   StringResource8(const char* data, int length)
52       : data_(data), length_(length) { }
length() const53   virtual size_t length() const { return length_; }
data() const54   virtual const char* data() const { return data_; }
55 
56  private:
57   const char* data_;
58   int length_;
59 };
60 
RunBaselineParser(const char * fname,Encoding encoding,int repeat,v8::Isolate * isolate,v8::Local<v8::Context> context)61 std::pair<v8::base::TimeDelta, v8::base::TimeDelta> RunBaselineParser(
62     const char* fname, Encoding encoding, int repeat, v8::Isolate* isolate,
63     v8::Local<v8::Context> context) {
64   int length = 0;
65   const byte* source = ReadFileAndRepeat(fname, &length, repeat);
66   v8::Local<v8::String> source_handle;
67   switch (encoding) {
68     case UTF8: {
69       source_handle = v8::String::NewFromUtf8(
70                           isolate, reinterpret_cast<const char*>(source),
71                           v8::NewStringType::kNormal).ToLocalChecked();
72       break;
73     }
74     case UTF16: {
75       source_handle =
76           v8::String::NewFromTwoByte(
77               isolate, reinterpret_cast<const uint16_t*>(source),
78               v8::NewStringType::kNormal, length / 2).ToLocalChecked();
79       break;
80     }
81     case LATIN1: {
82       StringResource8* string_resource =
83           new StringResource8(reinterpret_cast<const char*>(source), length);
84       source_handle = v8::String::NewExternalOneByte(isolate, string_resource)
85                           .ToLocalChecked();
86       break;
87     }
88   }
89   v8::base::TimeDelta parse_time1, parse_time2;
90   Handle<Script> script =
91       reinterpret_cast<i::Isolate*>(isolate)->factory()->NewScript(
92           v8::Utils::OpenHandle(*source_handle));
93   i::ScriptData* cached_data_impl = NULL;
94   // First round of parsing (produce data to cache).
95   {
96     Zone zone(reinterpret_cast<i::Isolate*>(isolate)->allocator(), ZONE_NAME);
97     ParseInfo info(&zone, script);
98     info.set_cached_data(&cached_data_impl);
99     info.set_compile_options(v8::ScriptCompiler::kProduceParserCache);
100     v8::base::ElapsedTimer timer;
101     timer.Start();
102     // Allow lazy parsing; otherwise we won't produce cached data.
103     info.set_allow_lazy_parsing();
104     bool success = Parser::ParseStatic(&info);
105     parse_time1 = timer.Elapsed();
106     if (!success) {
107       fprintf(stderr, "Parsing failed\n");
108       return std::make_pair(v8::base::TimeDelta(), v8::base::TimeDelta());
109     }
110   }
111   // Second round of parsing (consume cached data).
112   {
113     Zone zone(reinterpret_cast<i::Isolate*>(isolate)->allocator(), ZONE_NAME);
114     ParseInfo info(&zone, script);
115     info.set_cached_data(&cached_data_impl);
116     info.set_compile_options(v8::ScriptCompiler::kConsumeParserCache);
117     v8::base::ElapsedTimer timer;
118     timer.Start();
119     // Allow lazy parsing; otherwise cached data won't help.
120     info.set_allow_lazy_parsing();
121     bool success = Parser::ParseStatic(&info);
122     parse_time2 = timer.Elapsed();
123     if (!success) {
124       fprintf(stderr, "Parsing failed\n");
125       return std::make_pair(v8::base::TimeDelta(), v8::base::TimeDelta());
126     }
127   }
128   return std::make_pair(parse_time1, parse_time2);
129 }
130 
131 
main(int argc,char * argv[])132 int main(int argc, char* argv[]) {
133   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
134   v8::V8::InitializeICUDefaultLocation(argv[0]);
135   v8::Platform* platform = v8::platform::CreateDefaultPlatform();
136   v8::V8::InitializePlatform(platform);
137   v8::V8::Initialize();
138   v8::V8::InitializeExternalStartupData(argv[0]);
139 
140   Encoding encoding = LATIN1;
141   std::vector<std::string> fnames;
142   std::string benchmark;
143   int repeat = 1;
144   for (int i = 0; i < argc; ++i) {
145     if (strcmp(argv[i], "--latin1") == 0) {
146       encoding = LATIN1;
147     } else if (strcmp(argv[i], "--utf8") == 0) {
148       encoding = UTF8;
149     } else if (strcmp(argv[i], "--utf16") == 0) {
150       encoding = UTF16;
151     } else if (strncmp(argv[i], "--benchmark=", 12) == 0) {
152       benchmark = std::string(argv[i]).substr(12);
153     } else if (strncmp(argv[i], "--repeat=", 9) == 0) {
154       std::string repeat_str = std::string(argv[i]).substr(9);
155       repeat = atoi(repeat_str.c_str());
156     } else if (i > 0 && argv[i][0] != '-') {
157       fnames.push_back(std::string(argv[i]));
158     }
159   }
160   v8::Isolate::CreateParams create_params;
161   create_params.array_buffer_allocator =
162       v8::ArrayBuffer::Allocator::NewDefaultAllocator();
163   v8::Isolate* isolate = v8::Isolate::New(create_params);
164   {
165     v8::Isolate::Scope isolate_scope(isolate);
166     v8::HandleScope handle_scope(isolate);
167     v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
168     v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
169     DCHECK(!context.IsEmpty());
170     {
171       v8::Context::Scope scope(context);
172       double first_parse_total = 0;
173       double second_parse_total = 0;
174       for (size_t i = 0; i < fnames.size(); i++) {
175         std::pair<v8::base::TimeDelta, v8::base::TimeDelta> time =
176             RunBaselineParser(fnames[i].c_str(), encoding, repeat, isolate,
177                               context);
178         first_parse_total += time.first.InMillisecondsF();
179         second_parse_total += time.second.InMillisecondsF();
180       }
181       if (benchmark.empty()) benchmark = "Baseline";
182       printf("%s(FirstParseRunTime): %.f ms\n", benchmark.c_str(),
183              first_parse_total);
184       printf("%s(SecondParseRunTime): %.f ms\n", benchmark.c_str(),
185              second_parse_total);
186     }
187   }
188   v8::V8::Dispose();
189   v8::V8::ShutdownPlatform();
190   delete platform;
191   delete create_params.array_buffer_allocator;
192   return 0;
193 }
194