Upgrade to V8 3.6
Merge V8 at 3.6.6.11
Simple merge required updates to makefiles only.
Bug: 5688872
Change-Id: Ib38b7ffbcd409585f6cb6fccc59c767029cecc77
diff --git a/src/d8.cc b/src/d8.cc
index 4d7e988..55f0d4c 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -70,6 +70,7 @@
#ifndef V8_SHARED
LineEditor *LineEditor::first_ = NULL;
const char* Shell::kHistoryFileName = ".d8_history";
+const int Shell::kMaxHistoryEntries = 1000;
LineEditor::LineEditor(Type type, const char* name)
@@ -95,19 +96,19 @@
class DumbLineEditor: public LineEditor {
public:
DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { }
- virtual i::SmartPointer<char> Prompt(const char* prompt);
+ virtual i::SmartArrayPointer<char> Prompt(const char* prompt);
};
static DumbLineEditor dumb_line_editor;
-i::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) {
+i::SmartArrayPointer<char> DumbLineEditor::Prompt(const char* prompt) {
static const int kBufferSize = 256;
char buffer[kBufferSize];
printf("%s", prompt);
char* str = fgets(buffer, kBufferSize, stdin);
- return i::SmartPointer<char>(str ? i::StrDup(str) : str);
+ return i::SmartArrayPointer<char>(str ? i::StrDup(str) : str);
}
@@ -117,6 +118,7 @@
CounterCollection* Shell::counters_ = &local_counters_;
i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
Persistent<Context> Shell::utility_context_;
+LineEditor* Shell::console = NULL;
#endif // V8_SHARED
Persistent<Context> Shell::evaluation_context_;
@@ -176,8 +178,8 @@
// If all went well and the result wasn't undefined then print
// the returned value.
v8::String::Utf8Value str(result);
- const char* cstr = ToCString(str);
- printf("%s\n", cstr);
+ fwrite(*str, sizeof(**str), str.length(), stdout);
+ printf("\n");
}
return true;
}
@@ -203,13 +205,25 @@
int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
if (n != str.length()) {
printf("Error in fwrite\n");
- exit(1);
+ Exit(1);
}
}
return Undefined();
}
+Handle<Value> Shell::EnableProfiler(const Arguments& args) {
+ V8::ResumeProfiler();
+ return Undefined();
+}
+
+
+Handle<Value> Shell::DisableProfiler(const Arguments& args) {
+ V8::PauseProfiler();
+ return Undefined();
+}
+
+
Handle<Value> Shell::Read(const Arguments& args) {
String::Utf8Value file(args[0]);
if (*file == NULL) {
@@ -259,7 +273,7 @@
if (source.IsEmpty()) {
return ThrowException(String::New("Error loading file"));
}
- if (!ExecuteString(source, String::New(*file), false, false)) {
+ if (!ExecuteString(source, String::New(*file), false, true)) {
return ThrowException(String::New("Error executing file"));
}
}
@@ -283,18 +297,20 @@
size_t length = 0;
if (args[0]->IsUint32()) {
length = args[0]->Uint32Value();
- } else if (args[0]->IsNumber()) {
- double raw_length = args[0]->NumberValue();
+ } else {
+ Local<Number> number = args[0]->ToNumber();
+ if (number.IsEmpty() || !number->IsNumber()) {
+ return ThrowException(String::New("Array length must be a number."));
+ }
+ int32_t raw_length = number->ToInt32()->Int32Value();
if (raw_length < 0) {
return ThrowException(String::New("Array length must not be negative."));
}
- if (raw_length > kMaxLength) {
+ if (raw_length > static_cast<int32_t>(kMaxLength)) {
return ThrowException(
String::New("Array length exceeds maximum length."));
}
length = static_cast<size_t>(raw_length);
- } else {
- return ThrowException(String::New("Array length must be a number."));
}
if (length > static_cast<size_t>(kMaxLength)) {
return ThrowException(String::New("Array length exceeds maximum length."));
@@ -427,6 +443,7 @@
printf("%s\n", stack_trace_string);
}
}
+ printf("\n");
}
@@ -506,7 +523,7 @@
NULL : counters_file_->memory();
if (memory == NULL) {
printf("Could not map counters file %s\n", name);
- exit(1);
+ Exit(1);
}
counters_ = static_cast<CounterCollection*>(memory);
V8::SetCounterFunction(LookupCounter);
@@ -656,6 +673,10 @@
global_template->Set(String::New("load"), FunctionTemplate::New(Load));
global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
global_template->Set(String::New("version"), FunctionTemplate::New(Version));
+ global_template->Set(String::New("enableProfiler"),
+ FunctionTemplate::New(EnableProfiler));
+ global_template->Set(String::New("disableProfiler"),
+ FunctionTemplate::New(DisableProfiler));
// Bind the handlers for external arrays.
global_template->Set(String::New("Int8Array"),
@@ -683,7 +704,7 @@
global_template->Set(String::New("lol_is_enabled"), False());
#endif
-#ifndef V8_SHARED
+#if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
AddOSMethods(os_templ);
global_template->Set(String::New("os"), os_templ);
@@ -699,7 +720,7 @@
int bz2_result = startup_data_decompressor.Decompress();
if (bz2_result != BZ_OK) {
fprintf(stderr, "bzip error code: %d\n", bz2_result);
- exit(1);
+ Exit(1);
}
#endif
@@ -761,8 +782,18 @@
}
+void Shell::Exit(int exit_code) {
+ // Use _exit instead of exit to avoid races between isolate
+ // threads and static destructors.
+ fflush(stdout);
+ fflush(stderr);
+ _exit(exit_code);
+}
+
+
#ifndef V8_SHARED
void Shell::OnExit() {
+ if (console != NULL) console->Close();
if (i::FLAG_dump_counters) {
printf("+----------------------------------------+-------------+\n");
printf("| Name | Value |\n");
@@ -864,22 +895,22 @@
void Shell::RunShell() {
Locker locker;
Context::Scope context_scope(evaluation_context_);
- HandleScope handle_scope;
+ HandleScope outer_scope;
Handle<String> name = String::New("(d8)");
#ifndef V8_SHARED
- LineEditor* editor = LineEditor::Get();
- printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name());
+ console = LineEditor::Get();
+ printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
if (i::FLAG_debugger) {
printf("JavaScript debugger enabled\n");
}
- editor->Open();
+ console->Open();
while (true) {
- i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt);
+ i::SmartArrayPointer<char> input = console->Prompt(Shell::kPrompt);
if (input.is_empty()) break;
- editor->AddHistory(*input);
+ console->AddHistory(*input);
+ HandleScope inner_scope;
ExecuteString(String::New(*input), name, true, true);
}
- editor->Close();
#else
printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion());
static const int kBufferSize = 256;
@@ -887,6 +918,7 @@
char buffer[kBufferSize];
printf("%s", Shell::kPrompt);
if (fgets(buffer, kBufferSize, stdin) == NULL) break;
+ HandleScope inner_scope;
ExecuteString(String::New(buffer), name, true, true);
}
#endif // V8_SHARED
@@ -897,18 +929,24 @@
#ifndef V8_SHARED
class ShellThread : public i::Thread {
public:
- ShellThread(int no, i::Vector<const char> files)
+ // Takes ownership of the underlying char array of |files|.
+ ShellThread(int no, char* files)
: Thread("d8:ShellThread"),
no_(no), files_(files) { }
+
+ ~ShellThread() {
+ delete[] files_;
+ }
+
virtual void Run();
private:
int no_;
- i::Vector<const char> files_;
+ char* files_;
};
void ShellThread::Run() {
- char* ptr = const_cast<char*>(files_.start());
+ char* ptr = files_;
while ((ptr != NULL) && (*ptr != '\0')) {
// For each newline-separated line.
char* next_line = ReadLine(ptr);
@@ -921,23 +959,24 @@
// Prepare the context for this thread.
Locker locker;
- HandleScope scope;
+ HandleScope outer_scope;
Persistent<Context> thread_context = Shell::CreateEvaluationContext();
Context::Scope context_scope(thread_context);
while ((ptr != NULL) && (*ptr != '\0')) {
+ HandleScope inner_scope;
char* filename = ptr;
ptr = ReadWord(ptr);
// Skip empty strings.
if (strlen(filename) == 0) {
- break;
+ continue;
}
Handle<String> str = Shell::ReadFile(filename);
if (str.IsEmpty()) {
- printf("WARNING: %s not found\n", filename);
- break;
+ printf("File '%s' not found\n", filename);
+ Shell::Exit(1);
}
Shell::ExecuteString(str, String::New(filename), false, false);
@@ -950,12 +989,15 @@
#endif // V8_SHARED
-void SourceGroup::ExitShell(int exit_code) {
- // Use _exit instead of exit to avoid races between isolate
- // threads and static destructors.
- fflush(stdout);
- fflush(stderr);
- _exit(exit_code);
+SourceGroup::~SourceGroup() {
+#ifndef V8_SHARED
+ delete next_semaphore_;
+ next_semaphore_ = NULL;
+ delete done_semaphore_;
+ done_semaphore_ = NULL;
+ delete thread_;
+ thread_ = NULL;
+#endif // V8_SHARED
}
@@ -968,8 +1010,7 @@
Handle<String> file_name = String::New("unnamed");
Handle<String> source = String::New(argv_[i + 1]);
if (!Shell::ExecuteString(source, file_name, false, true)) {
- ExitShell(1);
- return;
+ Shell::Exit(1);
}
++i;
} else if (arg[0] == '-') {
@@ -981,12 +1022,10 @@
Handle<String> source = ReadFile(arg);
if (source.IsEmpty()) {
printf("Error reading '%s'\n", arg);
- ExitShell(1);
- return;
+ Shell::Exit(1);
}
if (!Shell::ExecuteString(source, file_name, false, true)) {
- ExitShell(1);
- return;
+ Shell::Exit(1);
}
}
}
@@ -1050,7 +1089,6 @@
if (thread_ == NULL) return;
if (Shell::options.last_run) {
thread_->Join();
- thread_ = NULL;
} else {
done_semaphore_->Wait();
}
@@ -1123,14 +1161,18 @@
return false;
#endif // V8_SHARED
options.num_isolates++;
+ } else if (strcmp(argv[i], "-p") == 0) {
+#ifdef V8_SHARED
+ printf("D8 with shared library does not support multi-threading\n");
+ return false;
+#else
+ options.num_parallel_files++;
+#endif // V8_SHARED
}
#ifdef V8_SHARED
else if (strcmp(argv[i], "--dump-counters") == 0) {
printf("D8 with shared library does not include counters\n");
return false;
- } else if (strcmp(argv[i], "-p") == 0) {
- printf("D8 with shared library does not support multi-threading\n");
- return false;
} else if (strcmp(argv[i], "--debugger") == 0) {
printf("Javascript debugger not included\n");
return false;
@@ -1140,6 +1182,8 @@
#ifndef V8_SHARED
// Run parallel threads if we are not using --isolate
+ options.parallel_files = new char*[options.num_parallel_files];
+ int parallel_files_set = 0;
for (int i = 1; i < argc; i++) {
if (argv[i] == NULL) continue;
if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
@@ -1148,25 +1192,21 @@
return false;
}
argv[i] = NULL;
- if (options.parallel_files == NULL) {
- options.parallel_files = new i::List<i::Vector<const char> >();
- }
- int size = 0;
- const char* files = ReadChars(argv[++i], &size);
- if (files == NULL) {
- printf("-p option incomplete\n");
- return false;
- }
+ i++;
+ options.parallel_files[parallel_files_set] = argv[i];
+ parallel_files_set++;
argv[i] = NULL;
- options.parallel_files->Add(i::Vector<const char>(files, size));
- delete[] files;
}
}
+ if (parallel_files_set != options.num_parallel_files) {
+ printf("-p requires a file containing a list of files as parameter\n");
+ return false;
+ }
#endif // V8_SHARED
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
- // set up isolated source groups
+ // Set up isolated source groups.
options.isolate_sources = new SourceGroup[options.num_isolates];
SourceGroup* current = options.isolate_sources;
current->Begin(argv, 1);
@@ -1189,14 +1229,22 @@
int Shell::RunMain(int argc, char* argv[]) {
#ifndef V8_SHARED
i::List<i::Thread*> threads(1);
- if (options.parallel_files != NULL)
- for (int i = 0; i < options.parallel_files->length(); i++) {
- i::Vector<const char> files = options.parallel_files->at(i);
+ if (options.parallel_files != NULL) {
+ for (int i = 0; i < options.num_parallel_files; i++) {
+ char* files = NULL;
+ { Locker lock(Isolate::GetCurrent());
+ int size = 0;
+ files = ReadChars(options.parallel_files[i], &size);
+ }
+ if (files == NULL) {
+ printf("File list '%s' not found\n", options.parallel_files[i]);
+ Exit(1);
+ }
ShellThread* thread = new ShellThread(threads.length(), files);
thread->Start();
threads.Add(thread);
}
-
+ }
for (int i = 1; i < options.num_isolates; ++i) {
options.isolate_sources[i].StartExecuteInThread();
}
@@ -1205,29 +1253,20 @@
Locker lock;
HandleScope scope;
Persistent<Context> context = CreateEvaluationContext();
- if (options.last_run) {
- // Keep using the same context in the interactive shell.
- evaluation_context_ = context;
-#ifndef V8_SHARED
- // If the interactive debugger is enabled make sure to activate
- // it before running the files passed on the command line.
- if (i::FLAG_debugger) {
- InstallUtilityScript();
- }
-#endif // V8_SHARED
- }
{
Context::Scope cscope(context);
options.isolate_sources[0].Execute();
}
- if (!options.last_run) {
+ if (options.last_run) {
+ // Keep using the same context in the interactive shell
+ evaluation_context_ = context;
+ } else {
context.Dispose();
}
#ifndef V8_SHARED
// Start preemption if threads have been created and preemption is enabled.
- if (options.parallel_files != NULL
- && threads.length() > 0
+ if (threads.length() > 0
&& options.use_preemption) {
Locker::StartPreemption(options.preemption_interval);
}
@@ -1239,12 +1278,16 @@
options.isolate_sources[i].WaitForThread();
}
- if (options.parallel_files != NULL)
- for (int i = 0; i < threads.length(); i++) {
- i::Thread* thread = threads[i];
- thread->Join();
- delete thread;
- }
+ for (int i = 0; i < threads.length(); i++) {
+ i::Thread* thread = threads[i];
+ thread->Join();
+ delete thread;
+ }
+
+ if (threads.length() > 0 && options.use_preemption) {
+ Locker lock;
+ Locker::StopPreemption();
+ }
#endif // V8_SHARED
return 0;
}
@@ -1289,9 +1332,7 @@
|| !options.script_executed )
&& !options.test_shell ) {
#ifndef V8_SHARED
- if (!i::FLAG_debugger) {
- InstallUtilityScript();
- }
+ InstallUtilityScript();
#endif // V8_SHARED
RunShell();
}