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

Side by Side Diff: samples/shell.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 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
« no previous file with comments | « include/v8-debug.h ('k') | src/SConscript » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include <v8.h> 28 #include <v8.h>
29 #include <v8-testing.h> 29 #include <v8-testing.h>
30 #include <assert.h> 30 #include <assert.h>
31 #include <fcntl.h> 31 #include <fcntl.h>
32 #include <string.h> 32 #include <string.h>
33 #include <stdio.h> 33 #include <stdio.h>
34 #include <stdlib.h> 34 #include <stdlib.h>
35 35
36 #include "../src/v8.h"
36 37
38 // TODO(isolates):
39 // o Either use V8 internal platform stuff for every platform or
40 // re-implement it.
41 // o Do not assume not WIN32 implies pthreads.
42 #ifndef WIN32
43 #include <pthread.h> // NOLINT
44 #include <unistd.h> // NOLINT
45 #endif
46
47 static void ExitShell(int exit_code) {
48 // Use _exit instead of exit to avoid races between isolate
49 // threads and static destructors.
50 fflush(stdout);
51 fflush(stderr);
52 _exit(exit_code);
53 }
54
55 v8::Persistent<v8::Context> CreateShellContext();
37 void RunShell(v8::Handle<v8::Context> context); 56 void RunShell(v8::Handle<v8::Context> context);
38 bool ExecuteString(v8::Handle<v8::String> source, 57 bool ExecuteString(v8::Handle<v8::String> source,
39 v8::Handle<v8::Value> name, 58 v8::Handle<v8::Value> name,
40 bool print_result, 59 bool print_result,
41 bool report_exceptions); 60 bool report_exceptions);
42 v8::Handle<v8::Value> Print(const v8::Arguments& args); 61 v8::Handle<v8::Value> Print(const v8::Arguments& args);
43 v8::Handle<v8::Value> Read(const v8::Arguments& args); 62 v8::Handle<v8::Value> Read(const v8::Arguments& args);
44 v8::Handle<v8::Value> Load(const v8::Arguments& args); 63 v8::Handle<v8::Value> Load(const v8::Arguments& args);
45 v8::Handle<v8::Value> Quit(const v8::Arguments& args); 64 v8::Handle<v8::Value> Quit(const v8::Arguments& args);
46 v8::Handle<v8::Value> Version(const v8::Arguments& args); 65 v8::Handle<v8::Value> Version(const v8::Arguments& args);
47 v8::Handle<v8::String> ReadFile(const char* name); 66 v8::Handle<v8::String> ReadFile(const char* name);
48 void ReportException(v8::TryCatch* handler); 67 void ReportException(v8::TryCatch* handler);
49 68
50 69
70 #ifndef WIN32
71 void* IsolateThreadEntry(void* arg);
72 #endif
73
74 static bool last_run = true;
75
76 class SourceGroup {
77 public:
78 SourceGroup() : argv_(NULL),
79 begin_offset_(0),
80 end_offset_(0),
81 next_semaphore_(NULL),
82 done_semaphore_(NULL) {
83 #ifndef WIN32
84 next_semaphore_ = v8::internal::OS::CreateSemaphore(0);
85 done_semaphore_ = v8::internal::OS::CreateSemaphore(0);
86 thread_ = 0;
87 #endif
88 }
89
90 void Begin(char** argv, int offset) {
91 argv_ = const_cast<const char**>(argv);
92 begin_offset_ = offset;
93 }
94
95 void End(int offset) { end_offset_ = offset; }
96
97 void Execute() {
98 for (int i = begin_offset_; i < end_offset_; ++i) {
99 const char* arg = argv_[i];
100 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
101 // Execute argument given to -e option directly.
102 v8::HandleScope handle_scope;
103 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
104 v8::Handle<v8::String> source = v8::String::New(argv_[i + 1]);
105 if (!ExecuteString(source, file_name, false, true)) {
106 ExitShell(1);
107 return;
108 }
109 ++i;
110 } else if (arg[0] == '-') {
111 // Ignore other options. They have been parsed already.
112 } else {
113 // Use all other arguments as names of files to load and run.
114 v8::HandleScope handle_scope;
115 v8::Handle<v8::String> file_name = v8::String::New(arg);
116 v8::Handle<v8::String> source = ReadFile(arg);
117 if (source.IsEmpty()) {
118 printf("Error reading '%s'\n", arg);
119 }
120 if (!ExecuteString(source, file_name, false, true)) {
121 ExitShell(1);
122 return;
123 }
124 }
125 }
126 }
127
128 #ifdef WIN32
129 void StartExecuteInThread() { ExecuteInThread(); }
130 void WaitForThread() {}
131
132 #else
133 void StartExecuteInThread() {
134 if (thread_ == 0) {
135 pthread_attr_t attr;
136 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
137 // which is not enough to parse the big literal expressions used in tests.
138 // The stack size should be at least StackGuard::kLimitSize + some
139 // OS-specific padding for thread startup code.
140 size_t stacksize = 2 << 20; // 2 Mb seems to be enough
141 pthread_attr_init(&attr);
142 pthread_attr_setstacksize(&attr, stacksize);
143 int error = pthread_create(&thread_, &attr, &IsolateThreadEntry, this);
144 if (error != 0) {
145 fprintf(stderr, "Error creating isolate thread.\n");
146 ExitShell(1);
147 }
148 }
149 next_semaphore_->Signal();
150 }
151
152 void WaitForThread() {
153 if (thread_ == 0) return;
154 if (last_run) {
155 pthread_join(thread_, NULL);
156 thread_ = 0;
157 } else {
158 done_semaphore_->Wait();
159 }
160 }
161 #endif // WIN32
162
163 private:
164 void ExecuteInThread() {
165 v8::Isolate* isolate = v8::Isolate::New();
166 do {
167 if (next_semaphore_ != NULL) next_semaphore_->Wait();
168 {
169 v8::Isolate::Scope iscope(isolate);
170 v8::HandleScope scope;
171 v8::Persistent<v8::Context> context = CreateShellContext();
172 {
173 v8::Context::Scope cscope(context);
174 Execute();
175 }
176 context.Dispose();
177 }
178 if (done_semaphore_ != NULL) done_semaphore_->Signal();
179 } while (!last_run);
180 isolate->Dispose();
181 }
182
183 const char** argv_;
184 int begin_offset_;
185 int end_offset_;
186 v8::internal::Semaphore* next_semaphore_;
187 v8::internal::Semaphore* done_semaphore_;
188 #ifndef WIN32
189 pthread_t thread_;
190 #endif
191
192 friend void* IsolateThreadEntry(void* arg);
193 };
194
195 #ifndef WIN32
196 void* IsolateThreadEntry(void* arg) {
197 reinterpret_cast<SourceGroup*>(arg)->ExecuteInThread();
198 return NULL;
199 }
200 #endif
201
202
203 static SourceGroup* isolate_sources = NULL;
204
205
51 int RunMain(int argc, char* argv[]) { 206 int RunMain(int argc, char* argv[]) {
207 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
52 v8::HandleScope handle_scope; 208 v8::HandleScope handle_scope;
53 // Create a template for the global object. 209 v8::Persistent<v8::Context> context = CreateShellContext();
54 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 210 // Enter the newly created execution environment.
55 // Bind the global 'print' function to the C++ Print callback. 211 context->Enter();
56 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
57 // Bind the global 'read' function to the C++ Read callback.
58 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
59 // Bind the global 'load' function to the C++ Load callback.
60 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
61 // Bind the 'quit' function
62 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
63 // Bind the 'version' function
64 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
65 // Create a new execution environment containing the built-in
66 // functions
67 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
68 if (context.IsEmpty()) { 212 if (context.IsEmpty()) {
69 printf("Error creating context\n"); 213 printf("Error creating context\n");
70 return 1; 214 return 1;
71 } 215 }
72 216
73 bool run_shell = (argc == 1); 217 bool run_shell = (argc == 1);
218 int num_isolates = 1;
74 for (int i = 1; i < argc; i++) { 219 for (int i = 1; i < argc; i++) {
75 // Enter the execution environment before evaluating any code. 220 if (strcmp(argv[i], "--isolate") == 0) ++num_isolates;
76 v8::Context::Scope context_scope(context); 221 }
77 const char* str = argv[i]; 222 if (isolate_sources == NULL) {
78 if (strcmp(str, "--shell") == 0) { 223 isolate_sources = new SourceGroup[num_isolates];
79 run_shell = true; 224 SourceGroup* current = isolate_sources;
80 } else if (strcmp(str, "-f") == 0) { 225 current->Begin(argv, 1);
81 // Ignore any -f flags for compatibility with the other stand- 226 for (int i = 1; i < argc; i++) {
82 // alone JavaScript engines. 227 const char* str = argv[i];
83 continue; 228 if (strcmp(str, "--isolate") == 0) {
84 } else if (strncmp(str, "--", 2) == 0) { 229 current->End(i);
85 printf("Warning: unknown flag %s.\nTry --help for options\n", str); 230 current++;
86 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { 231 current->Begin(argv, i + 1);
87 // Execute argument given to -e option directly 232 } else if (strcmp(str, "--shell") == 0) {
88 v8::HandleScope handle_scope; 233 run_shell = true;
89 v8::Handle<v8::String> file_name = v8::String::New("unnamed"); 234 } else if (strcmp(str, "-f") == 0) {
90 v8::Handle<v8::String> source = v8::String::New(argv[i + 1]); 235 // Ignore any -f flags for compatibility with the other stand-
91 if (!ExecuteString(source, file_name, false, true)) 236 // alone JavaScript engines.
92 return 1; 237 continue;
93 i++; 238 } else if (strncmp(str, "--", 2) == 0) {
94 } else { 239 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
95 // Use all other arguments as names of files to load and run.
96 v8::HandleScope handle_scope;
97 v8::Handle<v8::String> file_name = v8::String::New(str);
98 v8::Handle<v8::String> source = ReadFile(str);
99 if (source.IsEmpty()) {
100 printf("Error reading '%s'\n", str);
101 return 1;
102 } 240 }
103 if (!ExecuteString(source, file_name, false, true))
104 return 1;
105 } 241 }
242 current->End(argc);
106 } 243 }
244 for (int i = 1; i < num_isolates; ++i) {
245 isolate_sources[i].StartExecuteInThread();
246 }
247 isolate_sources[0].Execute();
107 if (run_shell) RunShell(context); 248 if (run_shell) RunShell(context);
249 for (int i = 1; i < num_isolates; ++i) {
250 isolate_sources[i].WaitForThread();
251 }
252 if (last_run) {
253 delete[] isolate_sources;
254 isolate_sources = NULL;
255 }
256 context->Exit();
108 context.Dispose(); 257 context.Dispose();
109 return 0; 258 return 0;
110 } 259 }
111 260
112 261
113 int main(int argc, char* argv[]) { 262 int main(int argc, char* argv[]) {
114 // Figure out if we're requested to stress the optimization 263 // Figure out if we're requested to stress the optimization
115 // infrastructure by running tests multiple times and forcing 264 // infrastructure by running tests multiple times and forcing
116 // optimization in the last run. 265 // optimization in the last run.
117 bool FLAG_stress_opt = false; 266 bool FLAG_stress_opt = false;
(...skipping 17 matching lines...) Expand all
135 int result = 0; 284 int result = 0;
136 if (FLAG_stress_opt || FLAG_stress_deopt) { 285 if (FLAG_stress_opt || FLAG_stress_deopt) {
137 v8::Testing::SetStressRunType(FLAG_stress_opt 286 v8::Testing::SetStressRunType(FLAG_stress_opt
138 ? v8::Testing::kStressTypeOpt 287 ? v8::Testing::kStressTypeOpt
139 : v8::Testing::kStressTypeDeopt); 288 : v8::Testing::kStressTypeDeopt);
140 int stress_runs = v8::Testing::GetStressRuns(); 289 int stress_runs = v8::Testing::GetStressRuns();
141 for (int i = 0; i < stress_runs && result == 0; i++) { 290 for (int i = 0; i < stress_runs && result == 0; i++) {
142 printf("============ Stress %d/%d ============\n", 291 printf("============ Stress %d/%d ============\n",
143 i + 1, stress_runs); 292 i + 1, stress_runs);
144 v8::Testing::PrepareStressRun(i); 293 v8::Testing::PrepareStressRun(i);
294 last_run = (i == stress_runs - 1);
145 result = RunMain(argc, argv); 295 result = RunMain(argc, argv);
146 } 296 }
147 printf("======== Full Deoptimization =======\n"); 297 printf("======== Full Deoptimization =======\n");
148 v8::Testing::DeoptimizeAll(); 298 v8::Testing::DeoptimizeAll();
149 } else { 299 } else {
150 result = RunMain(argc, argv); 300 result = RunMain(argc, argv);
151 } 301 }
152 v8::V8::Dispose(); 302 v8::V8::Dispose();
153 return result; 303 return result;
154 } 304 }
155 305
156 306
157 // Extracts a C string from a V8 Utf8Value. 307 // Extracts a C string from a V8 Utf8Value.
158 const char* ToCString(const v8::String::Utf8Value& value) { 308 const char* ToCString(const v8::String::Utf8Value& value) {
159 return *value ? *value : "<string conversion failed>"; 309 return *value ? *value : "<string conversion failed>";
160 } 310 }
161 311
162 312
313 // Creates a new execution environment containing the built-in
314 // functions.
315 v8::Persistent<v8::Context> CreateShellContext() {
316 // Create a template for the global object.
317 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
318 // Bind the global 'print' function to the C++ Print callback.
319 global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));
320 // Bind the global 'read' function to the C++ Read callback.
321 global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read));
322 // Bind the global 'load' function to the C++ Load callback.
323 global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load));
324 // Bind the 'quit' function
325 global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit));
326 // Bind the 'version' function
327 global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version));
328 return v8::Context::New(NULL, global);
329 }
330
331
163 // The callback that is invoked by v8 whenever the JavaScript 'print' 332 // The callback that is invoked by v8 whenever the JavaScript 'print'
164 // function is called. Prints its arguments on stdout separated by 333 // function is called. Prints its arguments on stdout separated by
165 // spaces and ending with a newline. 334 // spaces and ending with a newline.
166 v8::Handle<v8::Value> Print(const v8::Arguments& args) { 335 v8::Handle<v8::Value> Print(const v8::Arguments& args) {
167 bool first = true; 336 bool first = true;
168 for (int i = 0; i < args.Length(); i++) { 337 for (int i = 0; i < args.Length(); i++) {
169 v8::HandleScope handle_scope; 338 v8::HandleScope handle_scope;
170 if (first) { 339 if (first) {
171 first = false; 340 first = false;
172 } else { 341 } else {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 return v8::Undefined(); 391 return v8::Undefined();
223 } 392 }
224 393
225 394
226 // The callback that is invoked by v8 whenever the JavaScript 'quit' 395 // The callback that is invoked by v8 whenever the JavaScript 'quit'
227 // function is called. Quits. 396 // function is called. Quits.
228 v8::Handle<v8::Value> Quit(const v8::Arguments& args) { 397 v8::Handle<v8::Value> Quit(const v8::Arguments& args) {
229 // If not arguments are given args[0] will yield undefined which 398 // If not arguments are given args[0] will yield undefined which
230 // converts to the integer value 0. 399 // converts to the integer value 0.
231 int exit_code = args[0]->Int32Value(); 400 int exit_code = args[0]->Int32Value();
232 exit(exit_code); 401 ExitShell(exit_code);
233 return v8::Undefined(); 402 return v8::Undefined();
234 } 403 }
235 404
236 405
237 v8::Handle<v8::Value> Version(const v8::Arguments& args) { 406 v8::Handle<v8::Value> Version(const v8::Arguments& args) {
238 return v8::String::New(v8::V8::GetVersion()); 407 return v8::String::New(v8::V8::GetVersion());
239 } 408 }
240 409
241 410
242 // Reads a file into a v8 string. 411 // Reads a file into a v8 string.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 printf("^"); 516 printf("^");
348 } 517 }
349 printf("\n"); 518 printf("\n");
350 v8::String::Utf8Value stack_trace(try_catch->StackTrace()); 519 v8::String::Utf8Value stack_trace(try_catch->StackTrace());
351 if (stack_trace.length() > 0) { 520 if (stack_trace.length() > 0) {
352 const char* stack_trace_string = ToCString(stack_trace); 521 const char* stack_trace_string = ToCString(stack_trace);
353 printf("%s\n", stack_trace_string); 522 printf("%s\n", stack_trace_string);
354 } 523 }
355 } 524 }
356 } 525 }
OLDNEW
« no previous file with comments | « include/v8-debug.h ('k') | src/SConscript » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698