Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / v8 / src / d8.cc
index 661307f..356a64b 100644 (file)
 #include "include/v8-testing.h"
 #endif  // V8_SHARED
 
+#if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE)
+#include "src/gdb-jit.h"
+#endif
+
 #ifdef ENABLE_VTUNE_JIT_INTERFACE
 #include "src/third_party/vtune/v8-vtune.h"
 #endif
 
 #include "src/d8.h"
 
+#include "include/libplatform/libplatform.h"
 #ifndef V8_SHARED
 #include "src/api.h"
-#include "src/checks.h"
-#include "src/cpu.h"
+#include "src/base/cpu.h"
+#include "src/base/logging.h"
+#include "src/base/platform/platform.h"
 #include "src/d8-debug.h"
 #include "src/debug.h"
 #include "src/natives.h"
-#include "src/platform.h"
 #include "src/v8.h"
 #endif  // !V8_SHARED
 
@@ -50,8 +55,8 @@
 #include <unistd.h>  // NOLINT
 #endif
 
-#ifndef ASSERT
-#define ASSERT(condition) assert(condition)
+#ifndef DCHECK
+#define DCHECK(condition) assert(condition)
 #endif
 
 namespace v8 {
@@ -134,11 +139,12 @@ Handle<String> DumbLineEditor::Prompt(const char* prompt) {
 
 #ifndef V8_SHARED
 CounterMap* Shell::counter_map_;
-i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
+base::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
 CounterCollection Shell::local_counters_;
 CounterCollection* Shell::counters_ = &local_counters_;
-i::Mutex Shell::context_mutex_;
-const i::TimeTicks Shell::kInitialTicks = i::TimeTicks::HighResolutionNow();
+base::Mutex Shell::context_mutex_;
+const base::TimeTicks Shell::kInitialTicks =
+    base::TimeTicks::HighResolutionNow();
 Persistent<Context> Shell::utility_context_;
 #endif  // !V8_SHARED
 
@@ -164,6 +170,36 @@ const char* Shell::ToCString(const v8::String::Utf8Value& value) {
 }
 
 
+// Compile a string within the current v8 context.
+Local<UnboundScript> Shell::CompileString(
+    Isolate* isolate, Local<String> source, Local<Value> name,
+    v8::ScriptCompiler::CompileOptions compile_options) {
+  ScriptOrigin origin(name);
+  ScriptCompiler::Source script_source(source, origin);
+  Local<UnboundScript> script =
+      ScriptCompiler::CompileUnbound(isolate, &script_source, compile_options);
+
+  // Was caching requested & successful? Then compile again, now with cache.
+  if (script_source.GetCachedData()) {
+    if (compile_options == ScriptCompiler::kProduceCodeCache) {
+      compile_options = ScriptCompiler::kConsumeCodeCache;
+    } else if (compile_options == ScriptCompiler::kProduceParserCache) {
+      compile_options = ScriptCompiler::kConsumeParserCache;
+    } else {
+      DCHECK(false);  // A new compile option?
+    }
+    ScriptCompiler::Source cached_source(
+        source, origin, new v8::ScriptCompiler::CachedData(
+                            script_source.GetCachedData()->data,
+                            script_source.GetCachedData()->length,
+                            v8::ScriptCompiler::CachedData::BufferNotOwned));
+    script = ScriptCompiler::CompileUnbound(isolate, &cached_source,
+                                            compile_options);
+  }
+  return script;
+}
+
+
 // Executes a string within the current v8 context.
 bool Shell::ExecuteString(Isolate* isolate,
                           Handle<String> source,
@@ -182,10 +218,9 @@ bool Shell::ExecuteString(Isolate* isolate,
     // When debugging make exceptions appear to be uncaught.
     try_catch.SetVerbose(true);
   }
-  ScriptOrigin origin(name);
-  ScriptCompiler::Source script_source(source, origin);
+
   Handle<UnboundScript> script =
-      ScriptCompiler::CompileUnbound(isolate, &script_source);
+      Shell::CompileString(isolate, source, name, options.compile_options);
   if (script.IsEmpty()) {
     // Print errors that happened during compilation.
     if (report_exceptions && !FLAG_debugger)
@@ -200,13 +235,13 @@ bool Shell::ExecuteString(Isolate* isolate,
     realm->Exit();
     data->realm_current_ = data->realm_switch_;
     if (result.IsEmpty()) {
-      ASSERT(try_catch.HasCaught());
+      DCHECK(try_catch.HasCaught());
       // Print errors that happened during execution.
       if (report_exceptions && !FLAG_debugger)
         ReportException(isolate, &try_catch);
       return false;
     } else {
-      ASSERT(!try_catch.HasCaught());
+      DCHECK(!try_catch.HasCaught());
       if (print_result) {
 #if !defined(V8_SHARED)
         if (options.test_shell) {
@@ -290,9 +325,19 @@ int PerIsolateData::RealmIndexOrThrow(
 
 #ifndef V8_SHARED
 // performance.now() returns a time stamp as double, measured in milliseconds.
+// When FLAG_verify_predictable mode is enabled it returns current value
+// of Heap::allocations_count().
 void Shell::PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  i::TimeDelta delta = i::TimeTicks::HighResolutionNow() - kInitialTicks;
-  args.GetReturnValue().Set(delta.InMillisecondsF());
+  if (i::FLAG_verify_predictable) {
+    Isolate* v8_isolate = args.GetIsolate();
+    i::Heap* heap = reinterpret_cast<i::Isolate*>(v8_isolate)->heap();
+    args.GetReturnValue().Set(heap->synthetic_time());
+
+  } else {
+    base::TimeDelta delta =
+        base::TimeTicks::HighResolutionNow() - kInitialTicks;
+    args.GetReturnValue().Set(delta.InMillisecondsF());
+  }
 }
 #endif  // !V8_SHARED
 
@@ -552,7 +597,7 @@ void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
     printf("%s\n", exception_string);
   } else {
     // Print (filename):(line number): (message).
-    v8::String::Utf8Value filename(message->GetScriptResourceName());
+    v8::String::Utf8Value filename(message->GetScriptOrigin().ResourceName());
     const char* filename_string = ToCString(filename);
     int linenum = message->GetLineNumber();
     printf("%s:%i: %s\n", filename_string, linenum, exception_string);
@@ -666,7 +711,7 @@ Counter* CounterCollection::GetNextCounter() {
 
 
 void Shell::MapCounters(v8::Isolate* isolate, const char* name) {
-  counters_file_ = i::OS::MemoryMappedFile::create(
+  counters_file_ = base::OS::MemoryMappedFile::create(
       name, sizeof(CounterCollection), &local_counters_);
   void* memory = (counters_file_ == NULL) ?
       NULL : counters_file_->memory();
@@ -702,7 +747,7 @@ Counter* Shell::GetCounter(const char* name, bool is_histogram) {
       counter->Bind(name, is_histogram);
     }
   } else {
-    ASSERT(counter->is_histogram() == is_histogram);
+    DCHECK(counter->is_histogram() == is_histogram);
   }
   return counter;
 }
@@ -798,7 +843,7 @@ class BZip2Decompressor : public v8::StartupDataDecompressor {
                              int* raw_data_size,
                              const char* compressed_data,
                              int compressed_data_size) {
-    ASSERT_EQ(v8::StartupData::kBZip2,
+    DCHECK_EQ(v8::StartupData::kBZip2,
               v8::V8::GetCompressedStartupDataAlgorithm());
     unsigned int decompressed_size = *raw_data_size;
     int result =
@@ -863,11 +908,9 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
                        performance_template);
 #endif  // !V8_SHARED
 
-#if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
   Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate);
   AddOSMethods(isolate, os_templ);
   global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ);
-#endif  // !V8_SHARED && !_WIN32 && !_WIN64
 
   return global_template;
 }
@@ -889,9 +932,9 @@ void Shell::Initialize(Isolate* isolate) {
   if (i::StrLength(i::FLAG_map_counters) != 0)
     MapCounters(isolate, i::FLAG_map_counters);
   if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) {
-    V8::SetCounterFunction(LookupCounter);
-    V8::SetCreateHistogramFunction(CreateHistogram);
-    V8::SetAddHistogramSampleFunction(AddHistogramSample);
+    isolate->SetCounterFunction(LookupCounter);
+    isolate->SetCreateHistogramFunction(CreateHistogram);
+    isolate->SetAddHistogramSampleFunction(AddHistogramSample);
   }
 #endif  // !V8_SHARED
 }
@@ -911,13 +954,13 @@ void Shell::InitializeDebugger(Isolate* isolate) {
 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
 #ifndef V8_SHARED
   // This needs to be a critical section since this is not thread-safe
-  i::LockGuard<i::Mutex> lock_guard(&context_mutex_);
+  base::LockGuard<base::Mutex> lock_guard(&context_mutex_);
 #endif  // !V8_SHARED
   // Initialize the global objects
   Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
   EscapableHandleScope handle_scope(isolate);
   Local<Context> context = Context::New(isolate, NULL, global_template);
-  ASSERT(!context.IsEmpty());
+  DCHECK(!context.IsEmpty());
   Context::Scope scope(context);
 
 #ifndef V8_SHARED
@@ -1064,7 +1107,7 @@ static void ReadBufferWeakCallback(
 
 
 void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  ASSERT(sizeof(char) == sizeof(uint8_t));  // NOLINT
+  DCHECK(sizeof(char) == sizeof(uint8_t));  // NOLINT
   String::Utf8Value filename(args[0]);
   int length;
   if (*filename == NULL) {
@@ -1181,12 +1224,12 @@ Handle<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) {
 
 
 #ifndef V8_SHARED
-i::Thread::Options SourceGroup::GetThreadOptions() {
+base::Thread::Options SourceGroup::GetThreadOptions() {
   // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
   // which is not enough to parse the big literal expressions used in tests.
   // The stack size should be at least StackGuard::kLimitSize + some
   // OS-specific padding for thread startup code.  2Mbytes seems to be enough.
-  return i::Thread::Options("IsolateThread", 2 * MB);
+  return base::Thread::Options("IsolateThread", 2 * MB);
 }
 
 
@@ -1208,14 +1251,14 @@ void SourceGroup::ExecuteInThread() {
       }
       if (Shell::options.send_idle_notification) {
         const int kLongIdlePauseInMs = 1000;
-        V8::ContextDisposedNotification();
-        V8::IdleNotification(kLongIdlePauseInMs);
+        isolate->ContextDisposedNotification();
+        isolate->IdleNotification(kLongIdlePauseInMs);
       }
       if (Shell::options.invoke_weak_callbacks) {
         // By sending a low memory notifications, we will try hard to collect
         // all garbage and will therefore also invoke all weak callbacks of
         // actually unreachable persistent handles.
-        V8::LowMemoryNotification();
+        isolate->LowMemoryNotification();
       }
     }
     done_semaphore_.Signal();
@@ -1318,6 +1361,28 @@ bool Shell::SetOptions(int argc, char* argv[]) {
       printf("Javascript debugger not included\n");
       return false;
 #endif  // V8_SHARED
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+    } else if (strncmp(argv[i], "--natives_blob=", 15) == 0) {
+      options.natives_blob = argv[i] + 15;
+      argv[i] = NULL;
+    } else if (strncmp(argv[i], "--snapshot_blob=", 16) == 0) {
+      options.snapshot_blob = argv[i] + 16;
+      argv[i] = NULL;
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
+    } else if (strcmp(argv[i], "--cache") == 0 ||
+               strncmp(argv[i], "--cache=", 8) == 0) {
+      const char* value = argv[i] + 7;
+      if (!*value || strncmp(value, "=code", 6) == 0) {
+        options.compile_options = v8::ScriptCompiler::kProduceCodeCache;
+      } else if (strncmp(value, "=parse", 7) == 0) {
+        options.compile_options = v8::ScriptCompiler::kProduceParserCache;
+      } else if (strncmp(value, "=none", 6) == 0) {
+        options.compile_options = v8::ScriptCompiler::kNoCompileOptions;
+      } else {
+        printf("Unknown option to --cache.\n");
+        return false;
+      }
+      argv[i] = NULL;
     }
   }
 
@@ -1375,14 +1440,14 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
   }
   if (options.send_idle_notification) {
     const int kLongIdlePauseInMs = 1000;
-    V8::ContextDisposedNotification();
-    V8::IdleNotification(kLongIdlePauseInMs);
+    isolate->ContextDisposedNotification();
+    isolate->IdleNotification(kLongIdlePauseInMs);
   }
   if (options.invoke_weak_callbacks) {
     // By sending a low memory notifications, we will try hard to collect all
     // garbage and will therefore also invoke all weak callbacks of actually
     // unreachable persistent handles.
-    V8::LowMemoryNotification();
+    isolate->LowMemoryNotification();
   }
 
 #ifndef V8_SHARED
@@ -1476,9 +1541,67 @@ class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
 };
 
 
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+class StartupDataHandler {
+ public:
+  StartupDataHandler(const char* natives_blob,
+                     const char* snapshot_blob) {
+    Load(natives_blob, &natives_, v8::V8::SetNativesDataBlob);
+    Load(snapshot_blob, &snapshot_, v8::V8::SetSnapshotDataBlob);
+  }
+
+  ~StartupDataHandler() {
+    delete[] natives_.data;
+    delete[] snapshot_.data;
+  }
+
+ private:
+  void Load(const char* blob_file,
+            v8::StartupData* startup_data,
+            void (*setter_fn)(v8::StartupData*)) {
+    startup_data->data = NULL;
+    startup_data->compressed_size = 0;
+    startup_data->raw_size = 0;
+
+    if (!blob_file)
+      return;
+
+    FILE* file = fopen(blob_file, "rb");
+    if (!file)
+      return;
+
+    fseek(file, 0, SEEK_END);
+    startup_data->raw_size = ftell(file);
+    rewind(file);
+
+    startup_data->data = new char[startup_data->raw_size];
+    startup_data->compressed_size = fread(
+        const_cast<char*>(startup_data->data), 1, startup_data->raw_size,
+        file);
+    fclose(file);
+
+    if (startup_data->raw_size == startup_data->compressed_size)
+      (*setter_fn)(startup_data);
+  }
+
+  v8::StartupData natives_;
+  v8::StartupData snapshot_;
+
+  // Disallow copy & assign.
+  StartupDataHandler(const StartupDataHandler& other);
+  void operator=(const StartupDataHandler& other);
+};
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
+
+
 int Shell::Main(int argc, char* argv[]) {
   if (!SetOptions(argc, argv)) return 1;
   v8::V8::InitializeICU(options.icu_data_file);
+  v8::Platform* platform = v8::platform::CreateDefaultPlatform();
+  v8::V8::InitializePlatform(platform);
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+  StartupDataHandler startup_data(options.natives_blob, options.snapshot_blob);
+#endif
   SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg");
   SetFlagsFromString("--redirect-code-traces-to=code.asm");
   ShellArrayBufferAllocator array_buffer_allocator;
@@ -1492,15 +1615,21 @@ int Shell::Main(int argc, char* argv[]) {
   Isolate* isolate = Isolate::New();
 #ifndef V8_SHARED
   v8::ResourceConstraints constraints;
-  constraints.ConfigureDefaults(i::OS::TotalPhysicalMemory(),
-                                i::OS::MaxVirtualMemory(),
-                                i::OS::NumberOfProcessorsOnline());
+  constraints.ConfigureDefaults(base::OS::TotalPhysicalMemory(),
+                                base::OS::MaxVirtualMemory(),
+                                base::OS::NumberOfProcessorsOnline());
   v8::SetResourceConstraints(isolate, &constraints);
 #endif
   DumbLineEditor dumb_line_editor(isolate);
   {
     Isolate::Scope scope(isolate);
     Initialize(isolate);
+#if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE)
+    if (i::FLAG_gdbjit) {
+      v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
+                                     i::GDBJITInterface::EventHandler);
+    }
+#endif
 #ifdef ENABLE_VTUNE_JIT_INTERFACE
     vTune::InitializeVtuneForV8();
 #endif
@@ -1553,6 +1682,8 @@ int Shell::Main(int argc, char* argv[]) {
   }
   isolate->Dispose();
   V8::Dispose();
+  V8::ShutdownPlatform();
+  delete platform;
 
   OnExit();