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

Side by Side Diff: src/d8.cc

Issue 7318002: ported --isolate option to d8 and refactored to group together option parsing (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: small change Created 9 years, 5 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
« src/d8.h ('K') | « src/d8.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 23 matching lines...) Expand all
34 34
35 #include "v8.h" 35 #include "v8.h"
36 36
37 #include "d8.h" 37 #include "d8.h"
38 #include "d8-debug.h" 38 #include "d8-debug.h"
39 #include "debug.h" 39 #include "debug.h"
40 #include "api.h" 40 #include "api.h"
41 #include "natives.h" 41 #include "natives.h"
42 #include "platform.h" 42 #include "platform.h"
43 43
44 #if !defined(_WIN32) && !defined(_WIN64)
45 #include <unistd.h> // NOLINT
Yang 2011/07/07 16:04:49 necessary for _exit()
46 #endif
44 47
45 namespace v8 { 48 namespace v8 {
46 49
47 50
48 const char* Shell::kHistoryFileName = ".d8_history"; 51 const char* Shell::kHistoryFileName = ".d8_history";
49 const char* Shell::kPrompt = "d8> "; 52 const char* Shell::kPrompt = "d8> ";
50 53
51 54
52 LineEditor *LineEditor::first_ = NULL; 55 LineEditor *LineEditor::first_ = NULL;
53 56
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 return i::SmartPointer<char>(str ? i::StrDup(str) : str); 93 return i::SmartPointer<char>(str ? i::StrDup(str) : str);
91 } 94 }
92 95
93 96
94 CounterMap* Shell::counter_map_; 97 CounterMap* Shell::counter_map_;
95 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL; 98 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
96 CounterCollection Shell::local_counters_; 99 CounterCollection Shell::local_counters_;
97 CounterCollection* Shell::counters_ = &local_counters_; 100 CounterCollection* Shell::counters_ = &local_counters_;
98 Persistent<Context> Shell::utility_context_; 101 Persistent<Context> Shell::utility_context_;
99 Persistent<Context> Shell::evaluation_context_; 102 Persistent<Context> Shell::evaluation_context_;
103 i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
104 ShellOptions Shell::options;
100 105
101 106
102 bool CounterMap::Match(void* key1, void* key2) { 107 bool CounterMap::Match(void* key1, void* key2) {
103 const char* name1 = reinterpret_cast<const char*>(key1); 108 const char* name1 = reinterpret_cast<const char*>(key1);
104 const char* name2 = reinterpret_cast<const char*>(key2); 109 const char* name2 = reinterpret_cast<const char*>(key2);
105 return strcmp(name1, name2) == 0; 110 return strcmp(name1, name2) == 0;
106 } 111 }
107 112
108 113
109 // Converts a V8 value to a C string. 114 // Converts a V8 value to a C string.
110 const char* Shell::ToCString(const v8::String::Utf8Value& value) { 115 const char* Shell::ToCString(const v8::String::Utf8Value& value) {
111 return *value ? *value : "<string conversion failed>"; 116 return *value ? *value : "<string conversion failed>";
112 } 117 }
113 118
114 119
115 // Executes a string within the current v8 context. 120 // Executes a string within the current v8 context.
116 bool Shell::ExecuteString(Handle<String> source, 121 bool Shell::ExecuteString(Handle<String> source,
117 Handle<Value> name, 122 Handle<Value> name,
118 bool print_result, 123 bool print_result,
119 bool report_exceptions) { 124 bool report_exceptions) {
120 HandleScope handle_scope; 125 HandleScope handle_scope;
121 TryCatch try_catch; 126 TryCatch try_catch;
127 options.script_executed = true;
122 if (i::FLAG_debugger) { 128 if (i::FLAG_debugger) {
123 // When debugging make exceptions appear to be uncaught. 129 // When debugging make exceptions appear to be uncaught.
124 try_catch.SetVerbose(true); 130 try_catch.SetVerbose(true);
125 } 131 }
126 Handle<Script> script = Script::Compile(source, name); 132 Handle<Script> script = Script::Compile(source, name);
127 if (script.IsEmpty()) { 133 if (script.IsEmpty()) {
128 // Print errors that happened during compilation. 134 // Print errors that happened during compilation.
129 if (report_exceptions && !i::FLAG_debugger) 135 if (report_exceptions && !i::FLAG_debugger)
130 ReportException(&try_catch); 136 ReportException(&try_catch);
131 return false; 137 return false;
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 i::Vector<const char> shell_source = 539 i::Vector<const char> shell_source =
534 i::NativesCollection<i::D8>::GetRawScriptSource(source_index); 540 i::NativesCollection<i::D8>::GetRawScriptSource(source_index);
535 i::Vector<const char> shell_source_name = 541 i::Vector<const char> shell_source_name =
536 i::NativesCollection<i::D8>::GetScriptName(source_index); 542 i::NativesCollection<i::D8>::GetScriptName(source_index);
537 Handle<String> source = String::New(shell_source.start(), 543 Handle<String> source = String::New(shell_source.start(),
538 shell_source.length()); 544 shell_source.length());
539 Handle<String> name = String::New(shell_source_name.start(), 545 Handle<String> name = String::New(shell_source_name.start(),
540 shell_source_name.length()); 546 shell_source_name.length());
541 Handle<Script> script = Script::Compile(source, name); 547 Handle<Script> script = Script::Compile(source, name);
542 script->Run(); 548 script->Run();
543
544 // Mark the d8 shell script as native to avoid it showing up as normal source 549 // Mark the d8 shell script as native to avoid it showing up as normal source
545 // in the debugger. 550 // in the debugger.
546 i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script); 551 i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
547 i::Handle<i::Script> script_object = compiled_script->IsJSFunction() 552 i::Handle<i::Script> script_object = compiled_script->IsJSFunction()
548 ? i::Handle<i::Script>(i::Script::cast( 553 ? i::Handle<i::Script>(i::Script::cast(
549 i::JSFunction::cast(*compiled_script)->shared()->script())) 554 i::JSFunction::cast(*compiled_script)->shared()->script()))
550 : i::Handle<i::Script>(i::Script::cast( 555 : i::Handle<i::Script>(i::Script::cast(
551 i::SharedFunctionInfo::cast(*compiled_script)->script())); 556 i::SharedFunctionInfo::cast(*compiled_script)->script()));
552 script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE)); 557 script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
553 } 558 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 #endif 623 #endif
619 624
620 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(); 625 Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
621 AddOSMethods(os_templ); 626 AddOSMethods(os_templ);
622 global_template->Set(String::New("os"), os_templ); 627 global_template->Set(String::New("os"), os_templ);
623 628
624 return global_template; 629 return global_template;
625 } 630 }
626 631
627 632
628 void Shell::Initialize(bool test_shell) { 633 void Shell::Initialize() {
Yang 2011/07/07 16:04:49 test_shell is now a part of Shell::options and the
629 #ifdef COMPRESS_STARTUP_DATA_BZ2 634 #ifdef COMPRESS_STARTUP_DATA_BZ2
630 BZip2Decompressor startup_data_decompressor; 635 BZip2Decompressor startup_data_decompressor;
631 int bz2_result = startup_data_decompressor.Decompress(); 636 int bz2_result = startup_data_decompressor.Decompress();
632 if (bz2_result != BZ_OK) { 637 if (bz2_result != BZ_OK) {
633 fprintf(stderr, "bzip error code: %d\n", bz2_result); 638 fprintf(stderr, "bzip error code: %d\n", bz2_result);
634 exit(1); 639 exit(1);
635 } 640 }
636 #endif 641 #endif
637 642
638 Shell::counter_map_ = new CounterMap(); 643 Shell::counter_map_ = new CounterMap();
639 // Set up counters 644 // Set up counters
640 if (i::StrLength(i::FLAG_map_counters) != 0) 645 if (i::StrLength(i::FLAG_map_counters) != 0)
641 MapCounters(i::FLAG_map_counters); 646 MapCounters(i::FLAG_map_counters);
642 if (i::FLAG_dump_counters) { 647 if (i::FLAG_dump_counters) {
643 V8::SetCounterFunction(LookupCounter); 648 V8::SetCounterFunction(LookupCounter);
644 V8::SetCreateHistogramFunction(CreateHistogram); 649 V8::SetCreateHistogramFunction(CreateHistogram);
645 V8::SetAddHistogramSampleFunction(AddHistogramSample); 650 V8::SetAddHistogramSampleFunction(AddHistogramSample);
646 } 651 }
647 652
648 if (test_shell) return; 653 if (options.FLAG_test_shell) return;
649 654
650 Locker lock; 655 Locker lock;
651 HandleScope scope; 656 HandleScope scope;
652 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); 657 Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
653 utility_context_ = Context::New(NULL, global_template); 658 utility_context_ = Context::New(NULL, global_template);
654 659
655 #ifdef ENABLE_DEBUGGER_SUPPORT 660 #ifdef ENABLE_DEBUGGER_SUPPORT
656 // Start the debugger agent if requested. 661 // Start the debugger agent if requested.
657 if (i::FLAG_debugger_agent) { 662 if (i::FLAG_debugger_agent) {
658 v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true); 663 v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
659 } 664 }
660 665
661 // Start the in-process debugger if requested. 666 // Start the in-process debugger if requested.
662 if (i::FLAG_debugger && !i::FLAG_debugger_agent) { 667 if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
663 v8::Debug::SetDebugEventListener(HandleDebugEvent); 668 v8::Debug::SetDebugEventListener(HandleDebugEvent);
664 } 669 }
665 #endif 670 #endif
666 } 671 }
667 672
668 673
669 void Shell::RenewEvaluationContext() { 674 Persistent<Context> Shell::CreateEvaluationContext() {
675 // This needs to be a critical section since this is not thread-safe
676 context_mutex_->Lock();
Yang 2011/07/07 16:04:49 mark critical section because creating a context i
Søren Thygesen Gjesse 2011/07/08 08:09:12 Isn't this already handled by the use of lockers?
Yang 2011/07/08 10:03:46 Unfortunately, no. As it turns out, lockers only l
670 // Initialize the global objects 677 // Initialize the global objects
671 HandleScope scope;
672 Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); 678 Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
673 679 Persistent<Context> context = Context::New(NULL, global_template);
674 // (Re-)create the evaluation context 680 Context::Scope scope(context);
675 if (!evaluation_context_.IsEmpty()) {
676 evaluation_context_.Dispose();
677 }
678 evaluation_context_ = Context::New(NULL, global_template);
679 Context::Scope utility_scope(evaluation_context_);
680 681
681 i::JSArguments js_args = i::FLAG_js_arguments; 682 i::JSArguments js_args = i::FLAG_js_arguments;
682 i::Handle<i::FixedArray> arguments_array = 683 i::Handle<i::FixedArray> arguments_array =
683 FACTORY->NewFixedArray(js_args.argc()); 684 FACTORY->NewFixedArray(js_args.argc());
684 for (int j = 0; j < js_args.argc(); j++) { 685 for (int j = 0; j < js_args.argc(); j++) {
685 i::Handle<i::String> arg = 686 i::Handle<i::String> arg =
686 FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j])); 687 FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
687 arguments_array->set(j, *arg); 688 arguments_array->set(j, *arg);
688 } 689 }
689 i::Handle<i::JSArray> arguments_jsarray = 690 i::Handle<i::JSArray> arguments_jsarray =
690 FACTORY->NewJSArrayWithElements(arguments_array); 691 FACTORY->NewJSArrayWithElements(arguments_array);
691 evaluation_context_->Global()->Set(String::New("arguments"), 692 context->Global()->Set(String::New("arguments"),
692 Utils::ToLocal(arguments_jsarray)); 693 Utils::ToLocal(arguments_jsarray));
694 context_mutex_->Unlock();
695 return context;
693 } 696 }
694 697
695 698
696 void Shell::OnExit() { 699 void Shell::OnExit() {
697 if (i::FLAG_dump_counters) { 700 if (i::FLAG_dump_counters) {
698 ::printf("+----------------------------------------+-------------+\n"); 701 ::printf("+----------------------------------------+-------------+\n");
699 ::printf("| Name | Value |\n"); 702 ::printf("| Name | Value |\n");
700 ::printf("+----------------------------------------+-------------+\n"); 703 ::printf("+----------------------------------------+-------------+\n");
701 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) { 704 for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
702 Counter* counter = i.CurrentValue(); 705 Counter* counter = i.CurrentValue();
703 if (counter->is_histogram()) { 706 if (counter->is_histogram()) {
704 ::printf("| c:%-36s | %11i |\n", i.CurrentKey(), counter->count()); 707 ::printf("| c:%-36s | %11i |\n", i.CurrentKey(), counter->count());
705 ::printf("| t:%-36s | %11i |\n", 708 ::printf("| t:%-36s | %11i |\n",
706 i.CurrentKey(), 709 i.CurrentKey(),
707 counter->sample_total()); 710 counter->sample_total());
708 } else { 711 } else {
709 ::printf("| %-38s | %11i |\n", i.CurrentKey(), counter->count()); 712 ::printf("| %-38s | %11i |\n", i.CurrentKey(), counter->count());
710 } 713 }
711 } 714 }
712 ::printf("+----------------------------------------+-------------+\n"); 715 ::printf("+----------------------------------------+-------------+\n");
713 } 716 }
714 if (counters_file_ != NULL) 717 if (counters_file_ != NULL)
715 delete counters_file_; 718 delete counters_file_;
716 } 719 }
717 720
718 721
719 static char* ReadChars(const char* name, int* size_out) { 722 static char* ReadChars(const char* name, int* size_out) {
720 v8::Unlocker unlocker; // Release the V8 lock while reading files. 723 // Release the V8 lock while reading files.
724 v8::Unlocker unlocker(Isolate::GetCurrent());
Yang 2011/07/07 16:04:49 the default constructor takes the default isolate,
721 FILE* file = i::OS::FOpen(name, "rb"); 725 FILE* file = i::OS::FOpen(name, "rb");
722 if (file == NULL) return NULL; 726 if (file == NULL) return NULL;
723 727
724 fseek(file, 0, SEEK_END); 728 fseek(file, 0, SEEK_END);
725 int size = ftell(file); 729 int size = ftell(file);
726 rewind(file); 730 rewind(file);
727 731
728 char* chars = new char[size + 1]; 732 char* chars = new char[size + 1];
729 chars[size] = '\0'; 733 chars[size] = '\0';
730 for (int i = 0; i < size;) { 734 for (int i = 0; i < size;) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 : Thread("d8:ShellThread"), 803 : Thread("d8:ShellThread"),
800 no_(no), files_(files) { } 804 no_(no), files_(files) { }
801 virtual void Run(); 805 virtual void Run();
802 private: 806 private:
803 int no_; 807 int no_;
804 i::Vector<const char> files_; 808 i::Vector<const char> files_;
805 }; 809 };
806 810
807 811
808 void ShellThread::Run() { 812 void ShellThread::Run() {
809 // Prepare the context for this thread.
810 Locker locker;
811 HandleScope scope;
812 Handle<ObjectTemplate> global_template = Shell::CreateGlobalTemplate();
813
814 char* ptr = const_cast<char*>(files_.start()); 813 char* ptr = const_cast<char*>(files_.start());
815 while ((ptr != NULL) && (*ptr != '\0')) { 814 while ((ptr != NULL) && (*ptr != '\0')) {
816 // For each newline-separated line. 815 // For each newline-separated line.
817 char* next_line = ReadLine(ptr); 816 char* next_line = ReadLine(ptr);
818 817
819 if (*ptr == '#') { 818 if (*ptr == '#') {
820 // Skip comment lines. 819 // Skip comment lines.
821 ptr = next_line; 820 ptr = next_line;
822 continue; 821 continue;
823 } 822 }
824 823
825 Persistent<Context> thread_context = Context::New(NULL, global_template); 824 // Prepare the context for this thread.
Yang 2011/07/07 16:04:49 no point in locking earlier than necessary
825 Locker locker;
826 HandleScope scope;
827 Persistent<Context> thread_context = Shell::CreateEvaluationContext();
826 Context::Scope context_scope(thread_context); 828 Context::Scope context_scope(thread_context);
827 829
828 while ((ptr != NULL) && (*ptr != '\0')) { 830 while ((ptr != NULL) && (*ptr != '\0')) {
829 char* filename = ptr; 831 char* filename = ptr;
830 ptr = ReadWord(ptr); 832 ptr = ReadWord(ptr);
831 833
832 // Skip empty strings. 834 // Skip empty strings.
833 if (strlen(filename) == 0) { 835 if (strlen(filename) == 0) {
834 break; 836 break;
835 } 837 }
836 838
837 Handle<String> str = Shell::ReadFile(filename); 839 Handle<String> str = Shell::ReadFile(filename);
838 if (str.IsEmpty()) { 840 if (str.IsEmpty()) {
839 printf("WARNING: %s not found\n", filename); 841 printf("WARNING: %s not found\n", filename);
840 break; 842 break;
841 } 843 }
842 844
843 Shell::ExecuteString(str, String::New(filename), false, false); 845 Shell::ExecuteString(str, String::New(filename), false, false);
844 } 846 }
845 847
846 thread_context.Dispose(); 848 thread_context.Dispose();
847 ptr = next_line; 849 ptr = next_line;
848 } 850 }
849 } 851 }
850 852
851 int Shell::RunMain(int argc, char* argv[], bool* executed) { 853
Yang 2011/07/07 16:04:49 reused code from sample/shell.cc
852 // Default use preemption if threads are created. 854 void SourceGroup::ExitShell(int exit_code) {
853 bool use_preemption = true; 855 // Use _exit instead of exit to avoid races between isolate
854 856 // threads and static destructors.
855 // Default to use lowest possible thread preemption interval to test as many 857 fflush(stdout);
856 // edgecases as possible. 858 fflush(stderr);
857 int preemption_interval = 1; 859 _exit(exit_code);
858 860 }
861
862
863 void SourceGroup::Execute() {
864 for (int i = begin_offset_; i < end_offset_; ++i) {
865 const char* arg = argv_[i];
866 if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
867 // Execute argument given to -e option directly.
868 HandleScope handle_scope;
869 Handle<String> file_name = String::New("unnamed");
870 Handle<String> source = String::New(argv_[i + 1]);
871 if (!Shell::ExecuteString(source, file_name, false, true)) {
872 ExitShell(1);
873 return;
874 }
875 ++i;
876 } else if (arg[0] == '-') {
877 // Ignore other options. They have been parsed already.
878 } else {
879 // Use all other arguments as names of files to load and run.
880 HandleScope handle_scope;
881 Handle<String> file_name = String::New(arg);
882 Handle<String> source = ReadFile(arg);
883 if (source.IsEmpty()) {
884 printf("Error reading '%s'\n", arg);
885 ExitShell(1);
886 return;
887 }
888 if (!Shell::ExecuteString(source, file_name, false, true)) {
889 ExitShell(1);
890 return;
891 }
892 }
893 }
894 }
895
896
897 Handle<String> SourceGroup::ReadFile(const char* name) {
898 FILE* file = fopen(name, "rb");
899 if (file == NULL) return Handle<String>();
900
901 fseek(file, 0, SEEK_END);
902 int size = ftell(file);
903 rewind(file);
904
905 char* chars = new char[size + 1];
906 chars[size] = '\0';
907 for (int i = 0; i < size;) {
908 int read = fread(&chars[i], 1, size - i, file);
909 i += read;
910 }
911 fclose(file);
912 Handle<String> result = String::New(chars, size);
913 delete[] chars;
914 return result;
915 }
916
917
918 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
919 i::Thread::Options SourceGroup::GetThreadOptions() {
920 i::Thread::Options options;
921 options.name = "IsolateThread";
922 // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
923 // which is not enough to parse the big literal expressions used in tests.
924 // The stack size should be at least StackGuard::kLimitSize + some
925 // OS-specific padding for thread startup code.
926 options.stack_size = 2 << 20; // 2 Mb seems to be enough
927 return options;
928 }
929
930 void SourceGroup::ExecuteInThread() {
931 Isolate* isolate = Isolate::New();
932 do {
933 if (next_semaphore_ != NULL) next_semaphore_->Wait();
934 {
935 Isolate::Scope iscope(isolate);
936 Locker lock(isolate);
Yang 2011/07/07 16:04:49 the default constructor takes the default isolate,
937 HandleScope scope;
938 Persistent<Context> context = Shell::CreateEvaluationContext();
939 {
940 Context::Scope cscope(context);
941 Execute();
942 }
943 context.Dispose();
944 }
945 if (done_semaphore_ != NULL) done_semaphore_->Signal();
946 } while (!Shell::options.last_run);
947 isolate->Dispose();
948 }
949
950 void SourceGroup::StartExecuteInThread() {
951 if (thread_ == NULL) {
952 thread_ = new IsolateThread(this);
953 thread_->Start();
954 }
955 next_semaphore_->Signal();
956 }
957
958
959 void SourceGroup::WaitForThread() {
960 if (thread_ == NULL) return;
961 if (Shell::options.last_run) {
962 thread_->Join();
963 thread_ = NULL;
964 } else {
965 done_semaphore_->Wait();
966 }
967 }
968 #endif // USING_V8_SHARED
969
970
971 bool Shell::SetOptions(int argc, char* argv[]) {
Yang 2011/07/07 16:04:49 moved all the options parsing into this. the parse
972 Locker lock;
973
974 for (int i = 0; i < argc; i++) {
975 if (strcmp(argv[i], "--stress-opt") == 0) {
976 options.FLAG_stress_opt = true;
977 argv[i] = NULL;
978 } else if (strcmp(argv[i], "--stress-deopt") == 0) {
979 options.FLAG_stress_deopt = true;
980 argv[i] = NULL;
981 } else if (strcmp(argv[i], "--noalways-opt") == 0) {
982 // No support for stressing if we can't use --always-opt.
983 options.FLAG_stress_opt = false;
984 options.FLAG_stress_deopt = false;
985 } else if (strcmp(argv[i], "--shell") == 0) {
986 options.FLAG_interactive_shell = true;
987 argv[i] = NULL;
988 } else if (strcmp(argv[i], "--test") == 0) {
989 options.FLAG_test_shell = true;
990 argv[i] = NULL;
991 } else if (strcmp(argv[i], "--preemption") == 0) {
992 options.FLAG_preemption = true;
993 argv[i] = NULL;
994 } else if (strcmp(argv[i], "--no-preemption") == 0) {
995 options.FLAG_preemption = false;
996 argv[i] = NULL;
997 } else if (strcmp(argv[i], "--preemption-interval") == 0) {
998 if (++i < argc) {
999 argv[i-1] = NULL;
1000 char* end = NULL;
1001 options.preemption_interval = strtol(argv[i], &end, 10); // NOLINT
1002 if (options.preemption_interval <= 0
1003 || *end != '\0'
1004 || errno == ERANGE) {
1005 printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
1006 return false;
1007 }
1008 argv[i] = NULL;
1009 } else {
1010 printf("Missing value for --preemption-interval\n");
1011 return false;
1012 }
1013 } else if (strcmp(argv[i], "-f") == 0) {
1014 // Ignore any -f flags for compatibility with other stand-alone
1015 // JavaScript engines.
1016 continue;
1017 } else if (strcmp(argv[i], "--isolate") == 0) {
1018 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
1019 options.num_isolates++;
1020 #else // USING_V8_SHARED
1021 printf("Error: --isolate not supported when linked with shared "
1022 "library\n");
1023 ExitShell(1);
1024 #endif // USING_V8_SHARED
1025 }
1026 }
1027
1028 // Run parallel threads if we are not using --isolate
1029 for (int i = 1; i < argc; i++) {
1030 if (argv[i] == NULL) continue;
1031 if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
1032 if (options.num_isolates > 1) {
1033 printf("-p is not compatible with --isolate\n");
Yang 2011/07/07 16:04:49 either we have parallelism with -p or with --isola
1034 return false;
1035 }
1036 argv[i] = NULL;
1037 if (options.parallel_files == NULL) {
1038 options.parallel_files = new i::List<i::Vector<const char> >();
1039 }
1040 int size = 0;
1041 const char* files = ReadChars(argv[++i], &size);
1042 if (files == NULL) {
1043 printf("-p option incomplete\n");
1044 return false;
1045 }
1046 argv[i] = NULL;
1047 options.parallel_files->Add(i::Vector<const char>(files, size));
1048 }
1049 }
1050
1051 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
1052
1053 // set up isolated source groups
1054 options.isolate_sources = new SourceGroup[options.num_isolates];
1055 SourceGroup* current = options.isolate_sources;
1056 current->Begin(argv, 1);
1057 for (int i = 1; i < argc; i++) {
1058 const char* str = argv[i];
1059 if (strcmp(str, "--isolate") == 0) {
1060 current->End(i);
1061 current++;
1062 current->Begin(argv, i + 1);
1063 } else if (strncmp(argv[i], "--", 2) == 0) {
1064 printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
1065 }
1066 }
1067 current->End(argc);
1068
1069 return true;
1070 }
1071
1072
1073 int Shell::RunMain(int argc, char* argv[]) {
859 i::List<i::Thread*> threads(1); 1074 i::List<i::Thread*> threads(1);
860 1075
861 { 1076 {
862 // Since the thread below may spawn new threads accessing V8 holding the 1077 if (options.parallel_files != NULL)
Yang 2011/07/07 16:04:49 if parallel_files != NULL then there obviously are
863 // V8 lock here is mandatory. 1078 for (int i = 0; i < options.parallel_files->length(); i++) {
864 Locker locker; 1079 i::Vector<const char> files = options.parallel_files->at(i);
865 RenewEvaluationContext(); 1080 ShellThread* thread = new ShellThread(threads.length(), files);
866 Context::Scope context_scope(evaluation_context_);
867 for (int i = 1; i < argc; i++) {
868 char* str = argv[i];
869 if (strcmp(str, "--preemption") == 0) {
870 use_preemption = true;
871 } else if (strcmp(str, "--no-preemption") == 0) {
872 use_preemption = false;
873 } else if (strcmp(str, "--preemption-interval") == 0) {
874 if (i + 1 < argc) {
875 char* end = NULL;
876 preemption_interval = strtol(argv[++i], &end, 10); // NOLINT
877 if (preemption_interval <= 0 || *end != '\0' || errno == ERANGE) {
878 printf("Invalid value for --preemption-interval '%s'\n", argv[i]);
879 return 1;
880 }
881 } else {
882 printf("Missing value for --preemption-interval\n");
883 return 1;
884 }
885 } else if (strcmp(str, "-f") == 0) {
886 // Ignore any -f flags for compatibility with other stand-alone
887 // JavaScript engines.
888 continue;
889 } else if (strncmp(str, "--", 2) == 0) {
890 printf("Warning: unknown flag %s.\nTry --help for options\n", str);
891 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
892 // Execute argument given to -e option directly.
893 v8::HandleScope handle_scope;
894 v8::Handle<v8::String> file_name = v8::String::New("unnamed");
895 v8::Handle<v8::String> source = v8::String::New(argv[++i]);
896 (*executed) = true;
897 if (!ExecuteString(source, file_name, false, true)) {
898 OnExit();
899 return 1;
900 }
901 } else if (strcmp(str, "-p") == 0 && i + 1 < argc) {
902 int size = 0;
903 const char* files = ReadChars(argv[++i], &size);
904 if (files == NULL) return 1;
905 ShellThread* thread =
906 new ShellThread(threads.length(),
907 i::Vector<const char>(files, size));
908 thread->Start(); 1081 thread->Start();
909 threads.Add(thread); 1082 threads.Add(thread);
910 (*executed) = true; 1083 }
911 } else { 1084
912 // Use all other arguments as names of files to load and run. 1085 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
913 HandleScope handle_scope; 1086 for (int i = 1; i < options.num_isolates; ++i) {
914 Handle<String> file_name = v8::String::New(str); 1087 options.isolate_sources[i].StartExecuteInThread();
915 Handle<String> source = ReadFile(str); 1088 }
916 (*executed) = true; 1089 #endif // USING_V8_SHARED
917 if (source.IsEmpty()) { 1090
918 printf("Error reading '%s'\n", str); 1091 Locker lock;
919 return 1; 1092 HandleScope scope;
920 } 1093 Persistent<Context> context = CreateEvaluationContext();
921 if (!ExecuteString(source, file_name, false, true)) { 1094 {
922 OnExit(); 1095 Context::Scope cscope(context);
923 return 1; 1096 options.isolate_sources[0].Execute();
Yang 2011/07/07 16:04:49 this part executes even if single-threaded.
924 } 1097 }
925 } 1098 if (options.last_run) {
926 } 1099 // Keep using the same context in the interactive shell
927 1100 evaluation_context_ = context;
1101 } else {
1102 context.Dispose();
1103 }
928 // Start preemption if threads have been created and preemption is enabled. 1104 // Start preemption if threads have been created and preemption is enabled.
929 if (threads.length() > 0 && use_preemption) { 1105 if (options.parallel_files != NULL
930 Locker::StartPreemption(preemption_interval); 1106 && threads.length() > 0
931 } 1107 && options.FLAG_preemption) {
932 } 1108 Locker::StartPreemption(options.preemption_interval);
933 1109 }
934 for (int i = 0; i < threads.length(); i++) { 1110 }
935 i::Thread* thread = threads[i]; 1111
936 thread->Join(); 1112 #if !(defined(USING_V8_SHARED) || defined(V8_SHARED))
937 delete thread; 1113 for (int i = 1; i < options.num_isolates; ++i) {
938 } 1114 options.isolate_sources[i].WaitForThread();
1115 }
1116 #endif // USING_V8_SHARED
1117
1118 if (options.parallel_files != NULL)
1119 for (int i = 0; i < threads.length(); i++) {
1120 i::Thread* thread = threads[i];
1121 thread->Join();
1122 delete thread;
1123 }
1124
939 OnExit(); 1125 OnExit();
940 return 0; 1126 return 0;
941 } 1127 }
942 1128
943 1129
944 int Shell::Main(int argc, char* argv[]) { 1130 int Shell::Main(int argc, char* argv[]) {
945 // Figure out if we're requested to stress the optimization 1131 if (!SetOptions(argc, argv)) return 1;
946 // infrastructure by running tests multiple times and forcing 1132 Initialize();
947 // optimization in the last run.
948 bool FLAG_stress_opt = false;
949 bool FLAG_stress_deopt = false;
950 bool FLAG_interactive_shell = false;
951 bool FLAG_test_shell = false;
952 bool script_executed = false;
953
954 for (int i = 0; i < argc; i++) {
955 if (strcmp(argv[i], "--stress-opt") == 0) {
956 FLAG_stress_opt = true;
957 argv[i] = NULL;
958 } else if (strcmp(argv[i], "--stress-deopt") == 0) {
959 FLAG_stress_deopt = true;
960 argv[i] = NULL;
961 } else if (strcmp(argv[i], "--noalways-opt") == 0) {
962 // No support for stressing if we can't use --always-opt.
963 FLAG_stress_opt = false;
964 FLAG_stress_deopt = false;
965 } else if (strcmp(argv[i], "--shell") == 0) {
966 FLAG_interactive_shell = true;
967 argv[i] = NULL;
968 } else if (strcmp(argv[i], "--test") == 0) {
969 FLAG_test_shell = true;
970 argv[i] = NULL;
971 }
972 }
973
974 v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
975
976 Initialize(FLAG_test_shell);
977 1133
978 int result = 0; 1134 int result = 0;
979 if (FLAG_stress_opt || FLAG_stress_deopt) { 1135 if (options.FLAG_stress_opt || options.FLAG_stress_deopt) {
980 v8::Testing::SetStressRunType( 1136 Testing::SetStressRunType(
981 FLAG_stress_opt ? v8::Testing::kStressTypeOpt 1137 options.FLAG_stress_opt ? Testing::kStressTypeOpt
982 : v8::Testing::kStressTypeDeopt); 1138 : Testing::kStressTypeDeopt);
983 int stress_runs = v8::Testing::GetStressRuns(); 1139 int stress_runs = Testing::GetStressRuns();
984 for (int i = 0; i < stress_runs && result == 0; i++) { 1140 for (int i = 0; i < stress_runs && result == 0; i++) {
985 printf("============ Stress %d/%d ============\n", i + 1, stress_runs); 1141 printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
986 v8::Testing::PrepareStressRun(i); 1142 Testing::PrepareStressRun(i);
987 result = RunMain(argc, argv, &script_executed); 1143 options.last_run = (i == stress_runs - 1);
1144 result = RunMain(argc, argv);
988 } 1145 }
989 printf("======== Full Deoptimization =======\n"); 1146 printf("======== Full Deoptimization =======\n");
990 v8::Testing::DeoptimizeAll(); 1147 Testing::DeoptimizeAll();
991 } else { 1148 } else {
992 result = RunMain(argc, argv, &script_executed); 1149 result = RunMain(argc, argv);
993 } 1150 }
994 1151
995 #ifdef ENABLE_DEBUGGER_SUPPORT 1152 #ifdef ENABLE_DEBUGGER_SUPPORT
996 // Run remote debugger if requested, but never on --test 1153 // Run remote debugger if requested, but never on --test
997 if (i::FLAG_remote_debugger && !FLAG_test_shell) { 1154 if (i::FLAG_remote_debugger && !options.FLAG_test_shell) {
998 InstallUtilityScript(); 1155 InstallUtilityScript();
999 RunRemoteDebugger(i::FLAG_debugger_port); 1156 RunRemoteDebugger(i::FLAG_debugger_port);
1000 return 0; 1157 return 0;
1001 } 1158 }
1002 #endif 1159 #endif
1003 1160
1004 // Run interactive shell if explicitly requested or if no script has been 1161 // Run interactive shell if explicitly requested or if no script has been
1005 // executed, but never on --test 1162 // executed, but never on --test
1006 if ((FLAG_interactive_shell || !script_executed) && !FLAG_test_shell) { 1163
1164 if (( options.FLAG_interactive_shell
1165 || !options.script_executed )
1166 && !options.FLAG_test_shell ) {
1007 InstallUtilityScript(); 1167 InstallUtilityScript();
1008 RunShell(); 1168 RunShell();
1009 } 1169 }
1010 1170
1011 v8::V8::Dispose(); 1171 V8::Dispose();
1012 1172
1013 return result; 1173 return result;
1014 } 1174 }
1015 1175
1016 } // namespace v8 1176 } // namespace v8
1017 1177
1018 1178
1019 #ifndef GOOGLE3 1179 #ifndef GOOGLE3
1020 int main(int argc, char* argv[]) { 1180 int main(int argc, char* argv[]) {
1021 return v8::Shell::Main(argc, argv); 1181 return v8::Shell::Main(argc, argv);
1022 } 1182 }
1023 #endif 1183 #endif
OLDNEW
« src/d8.h ('K') | « src/d8.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698