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();
   }