V8 Project
d8.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 
6 // Defined when linking against shared lib on Windows.
7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED)
8 #define V8_SHARED
9 #endif
10 
11 #ifdef COMPRESS_STARTUP_DATA_BZ2
12 #include <bzlib.h>
13 #endif
14 
15 #include <errno.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/stat.h>
19 
20 #ifdef V8_SHARED
21 #include <assert.h>
22 #endif // V8_SHARED
23 
24 #ifndef V8_SHARED
25 #include <algorithm>
26 #endif // !V8_SHARED
27 
28 #ifdef V8_SHARED
29 #include "include/v8-testing.h"
30 #endif // V8_SHARED
31 
32 #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE)
33 #include "src/gdb-jit.h"
34 #endif
35 
36 #ifdef ENABLE_VTUNE_JIT_INTERFACE
38 #endif
39 
40 #include "src/d8.h"
41 
43 #ifndef V8_SHARED
44 #include "src/api.h"
45 #include "src/base/cpu.h"
46 #include "src/base/logging.h"
48 #include "src/base/sys-info.h"
50 #include "src/d8-debug.h"
51 #include "src/debug.h"
52 #include "src/natives.h"
53 #include "src/v8.h"
54 #endif // !V8_SHARED
55 
56 #if !defined(_WIN32) && !defined(_WIN64)
57 #include <unistd.h> // NOLINT
58 #else
59 #include <windows.h> // NOLINT
60 #if defined(_MSC_VER)
61 #include <crtdbg.h> // NOLINT
62 #endif // defined(_MSC_VER)
63 #endif // !defined(_WIN32) && !defined(_WIN64)
64 
65 #ifndef DCHECK
66 #define DCHECK(condition) assert(condition)
67 #endif
68 
69 namespace v8 {
70 
71 
72 static Handle<Value> Throw(Isolate* isolate, const char* message) {
73  return isolate->ThrowException(String::NewFromUtf8(isolate, message));
74 }
75 
76 
77 
79  public:
80  explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) {
81  HandleScope scope(isolate);
82  isolate->SetData(0, this);
83  }
84 
86  isolate_->SetData(0, NULL); // Not really needed, just to be sure...
87  }
88 
89  inline static PerIsolateData* Get(Isolate* isolate) {
90  return reinterpret_cast<PerIsolateData*>(isolate->GetData(0));
91  }
92 
93  class RealmScope {
94  public:
95  explicit RealmScope(PerIsolateData* data);
96  ~RealmScope();
97  private:
99  };
100 
101  private:
102  friend class Shell;
103  friend class RealmScope;
110 
112  int arg_offset);
113  int RealmFind(Handle<Context> context);
114 };
115 
116 
118 
119 
120 LineEditor::LineEditor(Type type, const char* name)
121  : type_(type), name_(name) {
122  if (current_ == NULL || current_->type_ < type) current_ = this;
123 }
124 
125 
126 class DumbLineEditor: public LineEditor {
127  public:
128  explicit DumbLineEditor(Isolate* isolate)
129  : LineEditor(LineEditor::DUMB, "dumb"), isolate_(isolate) { }
130  virtual Handle<String> Prompt(const char* prompt);
131  private:
133 };
134 
135 
137  printf("%s", prompt);
138 #if defined(__native_client__)
139  // Native Client libc is used to being embedded in Chrome and
140  // has trouble recognizing when to flush.
141  fflush(stdout);
142 #endif
144 }
145 
146 
147 #ifndef V8_SHARED
151 CounterCollection* Shell::counters_ = &local_counters_;
152 base::Mutex Shell::context_mutex_;
153 const base::TimeTicks Shell::kInitialTicks =
154  base::TimeTicks::HighResolutionNow();
156 #endif // !V8_SHARED
157 
160 const char* Shell::kPrompt = "d8> ";
161 
162 
163 #ifndef V8_SHARED
164 const int MB = 1024 * 1024;
165 
166 bool CounterMap::Match(void* key1, void* key2) {
167  const char* name1 = reinterpret_cast<const char*>(key1);
168  const char* name2 = reinterpret_cast<const char*>(key2);
169  return strcmp(name1, name2) == 0;
170 }
171 #endif // !V8_SHARED
172 
173 
174 // Converts a V8 value to a C string.
175 const char* Shell::ToCString(const v8::String::Utf8Value& value) {
176  return *value ? *value : "<string conversion failed>";
177 }
178 
179 
180 // Compile a string within the current v8 context.
182  Isolate* isolate, Local<String> source, Local<Value> name,
183  v8::ScriptCompiler::CompileOptions compile_options) {
184  ScriptOrigin origin(name);
185  ScriptCompiler::Source script_source(source, origin);
186  Local<UnboundScript> script =
187  ScriptCompiler::CompileUnbound(isolate, &script_source, compile_options);
188 
189  // Was caching requested & successful? Then compile again, now with cache.
190  if (script_source.GetCachedData()) {
191  if (compile_options == ScriptCompiler::kProduceCodeCache) {
192  compile_options = ScriptCompiler::kConsumeCodeCache;
193  } else if (compile_options == ScriptCompiler::kProduceParserCache) {
194  compile_options = ScriptCompiler::kConsumeParserCache;
195  } else {
196  DCHECK(false); // A new compile option?
197  }
198  ScriptCompiler::Source cached_source(
199  source, origin, new v8::ScriptCompiler::CachedData(
200  script_source.GetCachedData()->data,
201  script_source.GetCachedData()->length,
203  script = ScriptCompiler::CompileUnbound(isolate, &cached_source,
204  compile_options);
205  }
206  return script;
207 }
208 
209 
210 // Executes a string within the current v8 context.
212  Handle<String> source,
214  bool print_result,
215  bool report_exceptions) {
216 #ifndef V8_SHARED
217  bool FLAG_debugger = i::FLAG_debugger;
218 #else
219  bool FLAG_debugger = false;
220 #endif // !V8_SHARED
221  HandleScope handle_scope(isolate);
222  TryCatch try_catch;
223  options.script_executed = true;
224  if (FLAG_debugger) {
225  // When debugging make exceptions appear to be uncaught.
226  try_catch.SetVerbose(true);
227  }
228 
229  Handle<UnboundScript> script =
231  if (script.IsEmpty()) {
232  // Print errors that happened during compilation.
233  if (report_exceptions && !FLAG_debugger)
234  ReportException(isolate, &try_catch);
235  return false;
236  } else {
237  PerIsolateData* data = PerIsolateData::Get(isolate);
238  Local<Context> realm =
239  Local<Context>::New(isolate, data->realms_[data->realm_current_]);
240  realm->Enter();
241  Handle<Value> result = script->BindToCurrentContext()->Run();
242  realm->Exit();
243  data->realm_current_ = data->realm_switch_;
244  if (result.IsEmpty()) {
245  DCHECK(try_catch.HasCaught());
246  // Print errors that happened during execution.
247  if (report_exceptions && !FLAG_debugger)
248  ReportException(isolate, &try_catch);
249  return false;
250  } else {
251  DCHECK(!try_catch.HasCaught());
252  if (print_result) {
253 #if !defined(V8_SHARED)
254  if (options.test_shell) {
255 #endif
256  if (!result->IsUndefined()) {
257  // If all went well and the result wasn't undefined then print
258  // the returned value.
259  v8::String::Utf8Value str(result);
260  fwrite(*str, sizeof(**str), str.length(), stdout);
261  printf("\n");
262  }
263 #if !defined(V8_SHARED)
264  } else {
265  v8::TryCatch try_catch;
266  v8::Local<v8::Context> context =
268  v8::Context::Scope context_scope(context);
269  Handle<Object> global = context->Global();
270  Handle<Value> fun =
271  global->Get(String::NewFromUtf8(isolate, "Stringify"));
272  Handle<Value> argv[1] = { result };
273  Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
274  if (try_catch.HasCaught()) return true;
275  v8::String::Utf8Value str(s);
276  fwrite(*str, sizeof(**str), str.length(), stdout);
277  printf("\n");
278  }
279 #endif
280  }
281  return true;
282  }
283  }
284 }
285 
286 
288  data_->realm_count_ = 1;
289  data_->realm_current_ = 0;
290  data_->realm_switch_ = 0;
292  data_->realms_[0].Reset(data_->isolate_,
294 }
295 
296 
298  // Drop realms to avoid keeping them alive.
299  for (int i = 0; i < data_->realm_count_; ++i)
300  data_->realms_[i].Reset();
301  delete[] data_->realms_;
302  if (!data_->realm_shared_.IsEmpty())
303  data_->realm_shared_.Reset();
304 }
305 
306 
308  for (int i = 0; i < realm_count_; ++i) {
309  if (realms_[i] == context) return i;
310  }
311  return -1;
312 }
313 
314 
317  int arg_offset) {
318  if (args.Length() < arg_offset || !args[arg_offset]->IsNumber()) {
319  Throw(args.GetIsolate(), "Invalid argument");
320  return -1;
321  }
322  int index = args[arg_offset]->Int32Value();
323  if (index < 0 ||
324  index >= realm_count_ ||
325  realms_[index].IsEmpty()) {
326  Throw(args.GetIsolate(), "Invalid realm index");
327  return -1;
328  }
329  return index;
330 }
331 
332 
333 #ifndef V8_SHARED
334 // performance.now() returns a time stamp as double, measured in milliseconds.
335 // When FLAG_verify_predictable mode is enabled it returns current value
336 // of Heap::allocations_count().
338  if (i::FLAG_verify_predictable) {
339  Isolate* v8_isolate = args.GetIsolate();
340  i::Heap* heap = reinterpret_cast<i::Isolate*>(v8_isolate)->heap();
341  args.GetReturnValue().Set(heap->synthetic_time());
342  } else {
343  base::TimeDelta delta =
344  base::TimeTicks::HighResolutionNow() - kInitialTicks;
345  args.GetReturnValue().Set(delta.InMillisecondsF());
346  }
347 }
348 #endif // !V8_SHARED
349 
350 
351 // Realm.current() returns the index of the currently active realm.
353  Isolate* isolate = args.GetIsolate();
354  PerIsolateData* data = PerIsolateData::Get(isolate);
355  int index = data->RealmFind(isolate->GetEnteredContext());
356  if (index == -1) return;
357  args.GetReturnValue().Set(index);
358 }
359 
360 
361 // Realm.owner(o) returns the index of the realm that created o.
363  Isolate* isolate = args.GetIsolate();
364  PerIsolateData* data = PerIsolateData::Get(isolate);
365  if (args.Length() < 1 || !args[0]->IsObject()) {
366  Throw(args.GetIsolate(), "Invalid argument");
367  return;
368  }
369  int index = data->RealmFind(args[0]->ToObject()->CreationContext());
370  if (index == -1) return;
371  args.GetReturnValue().Set(index);
372 }
373 
374 
375 // Realm.global(i) returns the global object of realm i.
376 // (Note that properties of global objects cannot be read/written cross-realm.)
379  int index = data->RealmIndexOrThrow(args, 0);
380  if (index == -1) return;
381  args.GetReturnValue().Set(
382  Local<Context>::New(args.GetIsolate(), data->realms_[index])->Global());
383 }
384 
385 
386 // Realm.create() creates a new realm and returns its index.
388  Isolate* isolate = args.GetIsolate();
389  PerIsolateData* data = PerIsolateData::Get(isolate);
390  Persistent<Context>* old_realms = data->realms_;
391  int index = data->realm_count_;
392  data->realms_ = new Persistent<Context>[++data->realm_count_];
393  for (int i = 0; i < index; ++i) {
394  data->realms_[i].Reset(isolate, old_realms[i]);
395  }
396  delete[] old_realms;
397  Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
398  data->realms_[index].Reset(
399  isolate, Context::New(isolate, NULL, global_template));
400  args.GetReturnValue().Set(index);
401 }
402 
403 
404 // Realm.dispose(i) disposes the reference to the realm i.
406  Isolate* isolate = args.GetIsolate();
407  PerIsolateData* data = PerIsolateData::Get(isolate);
408  int index = data->RealmIndexOrThrow(args, 0);
409  if (index == -1) return;
410  if (index == 0 ||
411  index == data->realm_current_ || index == data->realm_switch_) {
412  Throw(args.GetIsolate(), "Invalid realm index");
413  return;
414  }
415  data->realms_[index].Reset();
416 }
417 
418 
419 // Realm.switch(i) switches to the realm i for consecutive interactive inputs.
421  Isolate* isolate = args.GetIsolate();
422  PerIsolateData* data = PerIsolateData::Get(isolate);
423  int index = data->RealmIndexOrThrow(args, 0);
424  if (index == -1) return;
425  data->realm_switch_ = index;
426 }
427 
428 
429 // Realm.eval(i, s) evaluates s in realm i and returns the result.
431  Isolate* isolate = args.GetIsolate();
432  PerIsolateData* data = PerIsolateData::Get(isolate);
433  int index = data->RealmIndexOrThrow(args, 0);
434  if (index == -1) return;
435  if (args.Length() < 2 || !args[1]->IsString()) {
436  Throw(args.GetIsolate(), "Invalid argument");
437  return;
438  }
439  ScriptCompiler::Source script_source(args[1]->ToString());
441  isolate, &script_source);
442  if (script.IsEmpty()) return;
443  Local<Context> realm = Local<Context>::New(isolate, data->realms_[index]);
444  realm->Enter();
445  Handle<Value> result = script->BindToCurrentContext()->Run();
446  realm->Exit();
447  args.GetReturnValue().Set(result);
448 }
449 
450 
451 // Realm.shared is an accessor for a single shared value across realms.
453  const PropertyCallbackInfo<Value>& info) {
454  Isolate* isolate = info.GetIsolate();
455  PerIsolateData* data = PerIsolateData::Get(isolate);
456  if (data->realm_shared_.IsEmpty()) return;
457  info.GetReturnValue().Set(data->realm_shared_);
458 }
459 
461  Local<Value> value,
462  const PropertyCallbackInfo<void>& info) {
463  Isolate* isolate = info.GetIsolate();
464  PerIsolateData* data = PerIsolateData::Get(isolate);
465  data->realm_shared_.Reset(isolate, value);
466 }
467 
468 
470  Write(args);
471  printf("\n");
472  fflush(stdout);
473 }
474 
475 
477  for (int i = 0; i < args.Length(); i++) {
478  HandleScope handle_scope(args.GetIsolate());
479  if (i != 0) {
480  printf(" ");
481  }
482 
483  // Explicitly catch potential exceptions in toString().
484  v8::TryCatch try_catch;
485  Handle<String> str_obj = args[i]->ToString();
486  if (try_catch.HasCaught()) {
487  try_catch.ReThrow();
488  return;
489  }
490 
491  v8::String::Utf8Value str(str_obj);
492  int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
493  if (n != str.length()) {
494  printf("Error in fwrite\n");
495  Exit(1);
496  }
497  }
498 }
499 
500 
502  String::Utf8Value file(args[0]);
503  if (*file == NULL) {
504  Throw(args.GetIsolate(), "Error loading file");
505  return;
506  }
507  Handle<String> source = ReadFile(args.GetIsolate(), *file);
508  if (source.IsEmpty()) {
509  Throw(args.GetIsolate(), "Error loading file");
510  return;
511  }
512  args.GetReturnValue().Set(source);
513 }
514 
515 
517  static const int kBufferSize = 256;
518  char buffer[kBufferSize];
519  Handle<String> accumulator = String::NewFromUtf8(isolate, "");
520  int length;
521  while (true) {
522  // Continue reading if the line ends with an escape '\\' or the line has
523  // not been fully read into the buffer yet (does not end with '\n').
524  // If fgets gets an error, just give up.
525  char* input = NULL;
526  input = fgets(buffer, kBufferSize, stdin);
527  if (input == NULL) return Handle<String>();
528  length = static_cast<int>(strlen(buffer));
529  if (length == 0) {
530  return accumulator;
531  } else if (buffer[length-1] != '\n') {
532  accumulator = String::Concat(
533  accumulator,
534  String::NewFromUtf8(isolate, buffer, String::kNormalString, length));
535  } else if (length > 1 && buffer[length-2] == '\\') {
536  buffer[length-2] = '\n';
537  accumulator = String::Concat(
538  accumulator, String::NewFromUtf8(isolate, buffer,
539  String::kNormalString, length - 1));
540  } else {
541  return String::Concat(
542  accumulator, String::NewFromUtf8(isolate, buffer,
543  String::kNormalString, length - 1));
544  }
545  }
546 }
547 
548 
550  for (int i = 0; i < args.Length(); i++) {
551  HandleScope handle_scope(args.GetIsolate());
552  String::Utf8Value file(args[i]);
553  if (*file == NULL) {
554  Throw(args.GetIsolate(), "Error loading file");
555  return;
556  }
557  Handle<String> source = ReadFile(args.GetIsolate(), *file);
558  if (source.IsEmpty()) {
559  Throw(args.GetIsolate(), "Error loading file");
560  return;
561  }
562  if (!ExecuteString(args.GetIsolate(),
563  source,
565  false,
566  true)) {
567  Throw(args.GetIsolate(), "Error executing file");
568  return;
569  }
570  }
571 }
572 
573 
575  int exit_code = args[0]->Int32Value();
576  OnExit();
577  exit(exit_code);
578 }
579 
580 
582  args.GetReturnValue().Set(
584 }
585 
586 
587 void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
588  HandleScope handle_scope(isolate);
589 #ifndef V8_SHARED
590  Handle<Context> utility_context;
591  bool enter_context = !isolate->InContext();
592  if (enter_context) {
593  utility_context = Local<Context>::New(isolate, utility_context_);
594  utility_context->Enter();
595  }
596 #endif // !V8_SHARED
597  v8::String::Utf8Value exception(try_catch->Exception());
598  const char* exception_string = ToCString(exception);
599  Handle<Message> message = try_catch->Message();
600  if (message.IsEmpty()) {
601  // V8 didn't provide any extra information about this error; just
602  // print the exception.
603  printf("%s\n", exception_string);
604  } else {
605  // Print (filename):(line number): (message).
606  v8::String::Utf8Value filename(message->GetScriptOrigin().ResourceName());
607  const char* filename_string = ToCString(filename);
608  int linenum = message->GetLineNumber();
609  printf("%s:%i: %s\n", filename_string, linenum, exception_string);
610  // Print line of source code.
611  v8::String::Utf8Value sourceline(message->GetSourceLine());
612  const char* sourceline_string = ToCString(sourceline);
613  printf("%s\n", sourceline_string);
614  // Print wavy underline (GetUnderline is deprecated).
615  int start = message->GetStartColumn();
616  for (int i = 0; i < start; i++) {
617  printf(" ");
618  }
619  int end = message->GetEndColumn();
620  for (int i = start; i < end; i++) {
621  printf("^");
622  }
623  printf("\n");
624  v8::String::Utf8Value stack_trace(try_catch->StackTrace());
625  if (stack_trace.length() > 0) {
626  const char* stack_trace_string = ToCString(stack_trace);
627  printf("%s\n", stack_trace_string);
628  }
629  }
630  printf("\n");
631 #ifndef V8_SHARED
632  if (enter_context) utility_context->Exit();
633 #endif // !V8_SHARED
634 }
635 
636 
637 #ifndef V8_SHARED
639  Handle<String> text,
640  Handle<String> full) {
641  EscapableHandleScope handle_scope(isolate);
642  v8::Local<v8::Context> utility_context =
643  v8::Local<v8::Context>::New(isolate, utility_context_);
644  v8::Context::Scope context_scope(utility_context);
645  Handle<Object> global = utility_context->Global();
646  Local<Value> fun =
647  global->Get(String::NewFromUtf8(isolate, "GetCompletions"));
648  static const int kArgc = 3;
649  v8::Local<v8::Context> evaluation_context =
650  v8::Local<v8::Context>::New(isolate, evaluation_context_);
651  Handle<Value> argv[kArgc] = { evaluation_context->Global(), text, full };
652  Local<Value> val = Local<Function>::Cast(fun)->Call(global, kArgc, argv);
653  return handle_scope.Escape(Local<Array>::Cast(val));
654 }
655 
656 
658  Handle<String> message) {
659  EscapableHandleScope handle_scope(isolate);
660  v8::Local<v8::Context> context =
661  v8::Local<v8::Context>::New(isolate, utility_context_);
662  v8::Context::Scope context_scope(context);
663  Handle<Object> global = context->Global();
664  Handle<Value> fun =
665  global->Get(String::NewFromUtf8(isolate, "DebugMessageDetails"));
666  static const int kArgc = 1;
667  Handle<Value> argv[kArgc] = { message };
668  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
669  return handle_scope.Escape(Local<Object>(Handle<Object>::Cast(val)));
670 }
671 
672 
674  Handle<String> command) {
675  EscapableHandleScope handle_scope(isolate);
676  v8::Local<v8::Context> context =
677  v8::Local<v8::Context>::New(isolate, utility_context_);
678  v8::Context::Scope context_scope(context);
679  Handle<Object> global = context->Global();
680  Handle<Value> fun =
681  global->Get(String::NewFromUtf8(isolate, "DebugCommandToJSONRequest"));
682  static const int kArgc = 1;
683  Handle<Value> argv[kArgc] = { command };
684  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
685  return handle_scope.Escape(Local<Value>(val));
686 }
687 
688 
689 int32_t* Counter::Bind(const char* name, bool is_histogram) {
690  int i;
691  for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
692  name_[i] = static_cast<char>(name[i]);
693  name_[i] = '\0';
694  is_histogram_ = is_histogram;
695  return ptr();
696 }
697 
698 
700  count_++;
701  sample_total_ += sample;
702 }
703 
704 
706  magic_number_ = 0xDEADFACE;
707  max_counters_ = kMaxCounters;
708  max_name_size_ = Counter::kMaxNameSize;
709  counters_in_use_ = 0;
710 }
711 
712 
714  if (counters_in_use_ == kMaxCounters) return NULL;
715  return &counters_[counters_in_use_++];
716 }
717 
718 
719 void Shell::MapCounters(v8::Isolate* isolate, const char* name) {
720  counters_file_ = base::OS::MemoryMappedFile::create(
721  name, sizeof(CounterCollection), &local_counters_);
722  void* memory = (counters_file_ == NULL) ?
723  NULL : counters_file_->memory();
724  if (memory == NULL) {
725  printf("Could not map counters file %s\n", name);
726  Exit(1);
727  }
728  counters_ = static_cast<CounterCollection*>(memory);
729  isolate->SetCounterFunction(LookupCounter);
730  isolate->SetCreateHistogramFunction(CreateHistogram);
731  isolate->SetAddHistogramSampleFunction(AddHistogramSample);
732 }
733 
734 
735 int CounterMap::Hash(const char* name) {
736  int h = 0;
737  int c;
738  while ((c = *name++) != 0) {
739  h += h << 5;
740  h += c;
741  }
742  return h;
743 }
744 
745 
746 Counter* Shell::GetCounter(const char* name, bool is_histogram) {
747  Counter* counter = counter_map_->Lookup(name);
748 
749  if (counter == NULL) {
750  counter = counters_->GetNextCounter();
751  if (counter != NULL) {
752  counter_map_->Set(name, counter);
753  counter->Bind(name, is_histogram);
754  }
755  } else {
756  DCHECK(counter->is_histogram() == is_histogram);
757  }
758  return counter;
759 }
760 
761 
762 int* Shell::LookupCounter(const char* name) {
763  Counter* counter = GetCounter(name, false);
764 
765  if (counter != NULL) {
766  return counter->ptr();
767  } else {
768  return NULL;
769  }
770 }
771 
772 
773 void* Shell::CreateHistogram(const char* name,
774  int min,
775  int max,
776  size_t buckets) {
777  return GetCounter(name, true);
778 }
779 
780 
781 void Shell::AddHistogramSample(void* histogram, int sample) {
782  Counter* counter = reinterpret_cast<Counter*>(histogram);
783  counter->AddSample(sample);
784 }
785 
786 
788  HandleScope scope(isolate);
789  // If we use the utility context, we have to set the security tokens so that
790  // utility, evaluation and debug context can all access each other.
791  v8::Local<v8::Context> utility_context =
792  v8::Local<v8::Context>::New(isolate, utility_context_);
793  v8::Local<v8::Context> evaluation_context =
794  v8::Local<v8::Context>::New(isolate, evaluation_context_);
795  utility_context->SetSecurityToken(Undefined(isolate));
796  evaluation_context->SetSecurityToken(Undefined(isolate));
797  v8::Context::Scope context_scope(utility_context);
798 
799  if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
800  // Install the debugger object in the utility scope
801  i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
802  debug->Load();
803  i::Handle<i::Context> debug_context = debug->debug_context();
804  i::Handle<i::JSObject> js_debug
805  = i::Handle<i::JSObject>(debug_context->global_object());
806  utility_context->Global()->Set(String::NewFromUtf8(isolate, "$debug"),
807  Utils::ToLocal(js_debug));
808  debug_context->set_security_token(
809  reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value());
810 
811  // Run the d8 shell utility script in the utility context
812  int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
813  i::Vector<const char> shell_source =
815  i::Vector<const char> shell_source_name =
817  Handle<String> source =
818  String::NewFromUtf8(isolate, shell_source.start(), String::kNormalString,
819  shell_source.length());
821  String::NewFromUtf8(isolate, shell_source_name.start(),
822  String::kNormalString, shell_source_name.length());
823  ScriptOrigin origin(name);
824  Handle<Script> script = Script::Compile(source, &origin);
825  script->Run();
826  // Mark the d8 shell script as native to avoid it showing up as normal source
827  // in the debugger.
828  i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
829  i::Handle<i::Script> script_object = compiled_script->IsJSFunction()
830  ? i::Handle<i::Script>(i::Script::cast(
831  i::JSFunction::cast(*compiled_script)->shared()->script()))
832  : i::Handle<i::Script>(i::Script::cast(
833  i::SharedFunctionInfo::cast(*compiled_script)->script()));
834  script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
835 
836  // Start the in-process debugger if requested.
837  if (i::FLAG_debugger) v8::Debug::SetDebugEventListener(HandleDebugEvent);
838 }
839 #endif // !V8_SHARED
840 
841 
842 #ifdef COMPRESS_STARTUP_DATA_BZ2
843 class BZip2Decompressor : public v8::StartupDataDecompressor {
844  public:
845  virtual ~BZip2Decompressor() { }
846 
847  protected:
848  virtual int DecompressData(char* raw_data,
849  int* raw_data_size,
850  const char* compressed_data,
851  int compressed_data_size) {
854  unsigned int decompressed_size = *raw_data_size;
855  int result =
856  BZ2_bzBuffToBuffDecompress(raw_data,
857  &decompressed_size,
858  const_cast<char*>(compressed_data),
859  compressed_data_size,
860  0, 1);
861  if (result == BZ_OK) {
862  *raw_data_size = decompressed_size;
863  }
864  return result;
865  }
866 };
867 #endif
868 
869 
871  Handle<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
872  global_template->Set(String::NewFromUtf8(isolate, "print"),
873  FunctionTemplate::New(isolate, Print));
874  global_template->Set(String::NewFromUtf8(isolate, "write"),
875  FunctionTemplate::New(isolate, Write));
876  global_template->Set(String::NewFromUtf8(isolate, "read"),
877  FunctionTemplate::New(isolate, Read));
878  global_template->Set(String::NewFromUtf8(isolate, "readbuffer"),
879  FunctionTemplate::New(isolate, ReadBuffer));
880  global_template->Set(String::NewFromUtf8(isolate, "readline"),
881  FunctionTemplate::New(isolate, ReadLine));
882  global_template->Set(String::NewFromUtf8(isolate, "load"),
883  FunctionTemplate::New(isolate, Load));
884  global_template->Set(String::NewFromUtf8(isolate, "quit"),
885  FunctionTemplate::New(isolate, Quit));
886  global_template->Set(String::NewFromUtf8(isolate, "version"),
887  FunctionTemplate::New(isolate, Version));
888 
889  // Bind the Realm object.
890  Handle<ObjectTemplate> realm_template = ObjectTemplate::New(isolate);
891  realm_template->Set(String::NewFromUtf8(isolate, "current"),
892  FunctionTemplate::New(isolate, RealmCurrent));
893  realm_template->Set(String::NewFromUtf8(isolate, "owner"),
894  FunctionTemplate::New(isolate, RealmOwner));
895  realm_template->Set(String::NewFromUtf8(isolate, "global"),
896  FunctionTemplate::New(isolate, RealmGlobal));
897  realm_template->Set(String::NewFromUtf8(isolate, "create"),
898  FunctionTemplate::New(isolate, RealmCreate));
899  realm_template->Set(String::NewFromUtf8(isolate, "dispose"),
900  FunctionTemplate::New(isolate, RealmDispose));
901  realm_template->Set(String::NewFromUtf8(isolate, "switch"),
902  FunctionTemplate::New(isolate, RealmSwitch));
903  realm_template->Set(String::NewFromUtf8(isolate, "eval"),
904  FunctionTemplate::New(isolate, RealmEval));
905  realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"),
906  RealmSharedGet, RealmSharedSet);
907  global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template);
908 
909 #ifndef V8_SHARED
910  Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate);
911  performance_template->Set(String::NewFromUtf8(isolate, "now"),
912  FunctionTemplate::New(isolate, PerformanceNow));
913  global_template->Set(String::NewFromUtf8(isolate, "performance"),
914  performance_template);
915 #endif // !V8_SHARED
916 
917  Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate);
918  AddOSMethods(isolate, os_templ);
919  global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ);
920 
921  return global_template;
922 }
923 
924 
925 void Shell::Initialize(Isolate* isolate) {
926 #ifdef COMPRESS_STARTUP_DATA_BZ2
927  BZip2Decompressor startup_data_decompressor;
928  int bz2_result = startup_data_decompressor.Decompress();
929  if (bz2_result != BZ_OK) {
930  fprintf(stderr, "bzip error code: %d\n", bz2_result);
931  Exit(1);
932  }
933 #endif
934 
935 #ifndef V8_SHARED
937  // Set up counters
938  if (i::StrLength(i::FLAG_map_counters) != 0)
939  MapCounters(isolate, i::FLAG_map_counters);
940  if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) {
941  isolate->SetCounterFunction(LookupCounter);
942  isolate->SetCreateHistogramFunction(CreateHistogram);
943  isolate->SetAddHistogramSampleFunction(AddHistogramSample);
944  }
945 #endif // !V8_SHARED
946 }
947 
948 
950  if (options.test_shell) return;
951 #ifndef V8_SHARED
952  HandleScope scope(isolate);
953  Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
954  utility_context_.Reset(isolate,
955  Context::New(isolate, NULL, global_template));
956 #endif // !V8_SHARED
957 }
958 
959 
961 #ifndef V8_SHARED
962  // This needs to be a critical section since this is not thread-safe
963  base::LockGuard<base::Mutex> lock_guard(&context_mutex_);
964 #endif // !V8_SHARED
965  // Initialize the global objects
966  Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
967  EscapableHandleScope handle_scope(isolate);
968  Local<Context> context = Context::New(isolate, NULL, global_template);
969  DCHECK(!context.IsEmpty());
970  Context::Scope scope(context);
971 
972 #ifndef V8_SHARED
973  i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
974  i::JSArguments js_args = i::FLAG_js_arguments;
975  i::Handle<i::FixedArray> arguments_array =
976  factory->NewFixedArray(js_args.argc);
977  for (int j = 0; j < js_args.argc; j++) {
979  factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked();
980  arguments_array->set(j, *arg);
981  }
982  i::Handle<i::JSArray> arguments_jsarray =
983  factory->NewJSArrayWithElements(arguments_array);
984  context->Global()->Set(String::NewFromUtf8(isolate, "arguments"),
985  Utils::ToLocal(arguments_jsarray));
986 #endif // !V8_SHARED
987  return handle_scope.Escape(context);
988 }
989 
990 
991 void Shell::Exit(int exit_code) {
992  // Use _exit instead of exit to avoid races between isolate
993  // threads and static destructors.
994  fflush(stdout);
995  fflush(stderr);
996  _exit(exit_code);
997 }
998 
999 
1000 #ifndef V8_SHARED
1003  const char* key;
1004 };
1005 
1006 
1007 inline bool operator<(const CounterAndKey& lhs, const CounterAndKey& rhs) {
1008  return strcmp(lhs.key, rhs.key) < 0;
1009 }
1010 #endif // !V8_SHARED
1011 
1012 
1014  LineEditor* line_editor = LineEditor::Get();
1015  if (line_editor) line_editor->Close();
1016 #ifndef V8_SHARED
1017  if (i::FLAG_dump_counters) {
1018  int number_of_counters = 0;
1019  for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
1020  number_of_counters++;
1021  }
1022  CounterAndKey* counters = new CounterAndKey[number_of_counters];
1023  int j = 0;
1024  for (CounterMap::Iterator i(counter_map_); i.More(); i.Next(), j++) {
1025  counters[j].counter = i.CurrentValue();
1026  counters[j].key = i.CurrentKey();
1027  }
1028  std::sort(counters, counters + number_of_counters);
1029  printf("+----------------------------------------------------------------+"
1030  "-------------+\n");
1031  printf("| Name |"
1032  " Value |\n");
1033  printf("+----------------------------------------------------------------+"
1034  "-------------+\n");
1035  for (j = 0; j < number_of_counters; j++) {
1036  Counter* counter = counters[j].counter;
1037  const char* key = counters[j].key;
1038  if (counter->is_histogram()) {
1039  printf("| c:%-60s | %11i |\n", key, counter->count());
1040  printf("| t:%-60s | %11i |\n", key, counter->sample_total());
1041  } else {
1042  printf("| %-62s | %11i |\n", key, counter->count());
1043  }
1044  }
1045  printf("+----------------------------------------------------------------+"
1046  "-------------+\n");
1047  delete [] counters;
1048  }
1049  delete counters_file_;
1050  delete counter_map_;
1051 #endif // !V8_SHARED
1052 }
1053 
1054 
1055 
1056 static FILE* FOpen(const char* path, const char* mode) {
1057 #if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
1058  FILE* result;
1059  if (fopen_s(&result, path, mode) == 0) {
1060  return result;
1061  } else {
1062  return NULL;
1063  }
1064 #else
1065  FILE* file = fopen(path, mode);
1066  if (file == NULL) return NULL;
1067  struct stat file_stat;
1068  if (fstat(fileno(file), &file_stat) != 0) return NULL;
1069  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
1070  if (is_regular_file) return file;
1071  fclose(file);
1072  return NULL;
1073 #endif
1074 }
1075 
1076 
1077 static char* ReadChars(Isolate* isolate, const char* name, int* size_out) {
1078  FILE* file = FOpen(name, "rb");
1079  if (file == NULL) return NULL;
1080 
1081  fseek(file, 0, SEEK_END);
1082  int size = ftell(file);
1083  rewind(file);
1084 
1085  char* chars = new char[size + 1];
1086  chars[size] = '\0';
1087  for (int i = 0; i < size;) {
1088  int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
1089  i += read;
1090  }
1091  fclose(file);
1092  *size_out = size;
1093  return chars;
1094 }
1095 
1096 
1098  uint8_t* data;
1100 };
1101 
1102 
1105  size_t byte_length = data.GetValue()->ByteLength();
1107  -static_cast<intptr_t>(byte_length));
1108 
1109  delete[] data.GetParameter()->data;
1110  data.GetParameter()->handle.Reset();
1111  delete data.GetParameter();
1112 }
1113 
1114 
1116  DCHECK(sizeof(char) == sizeof(uint8_t)); // NOLINT
1117  String::Utf8Value filename(args[0]);
1118  int length;
1119  if (*filename == NULL) {
1120  Throw(args.GetIsolate(), "Error loading file");
1121  return;
1122  }
1123 
1124  Isolate* isolate = args.GetIsolate();
1126  data->data = reinterpret_cast<uint8_t*>(
1127  ReadChars(args.GetIsolate(), *filename, &length));
1128  if (data->data == NULL) {
1129  delete data;
1130  Throw(args.GetIsolate(), "Error reading file");
1131  return;
1132  }
1133  Handle<v8::ArrayBuffer> buffer =
1134  ArrayBuffer::New(isolate, data->data, length);
1135  data->handle.Reset(isolate, buffer);
1136  data->handle.SetWeak(data, ReadBufferWeakCallback);
1137  data->handle.MarkIndependent();
1138  isolate->AdjustAmountOfExternalAllocatedMemory(length);
1139 
1140  args.GetReturnValue().Set(buffer);
1141 }
1142 
1143 
1144 // Reads a file into a v8 string.
1145 Handle<String> Shell::ReadFile(Isolate* isolate, const char* name) {
1146  int size = 0;
1147  char* chars = ReadChars(isolate, name, &size);
1148  if (chars == NULL) return Handle<String>();
1149  Handle<String> result =
1151  delete[] chars;
1152  return result;
1153 }
1154 
1155 
1156 void Shell::RunShell(Isolate* isolate) {
1157  HandleScope outer_scope(isolate);
1158  v8::Local<v8::Context> context =
1159  v8::Local<v8::Context>::New(isolate, evaluation_context_);
1160  v8::Context::Scope context_scope(context);
1161  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1162  Handle<String> name = String::NewFromUtf8(isolate, "(d8)");
1163  LineEditor* console = LineEditor::Get();
1164  printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
1165  console->Open(isolate);
1166  while (true) {
1167  HandleScope inner_scope(isolate);
1168  Handle<String> input = console->Prompt(Shell::kPrompt);
1169  if (input.IsEmpty()) break;
1170  ExecuteString(isolate, input, name, true, true);
1171  }
1172  printf("\n");
1173 }
1174 
1175 
1177 #ifndef V8_SHARED
1178  delete thread_;
1179  thread_ = NULL;
1180 #endif // !V8_SHARED
1181 }
1182 
1183 
1185  bool exception_was_thrown = false;
1186  for (int i = begin_offset_; i < end_offset_; ++i) {
1187  const char* arg = argv_[i];
1188  if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
1189  // Execute argument given to -e option directly.
1190  HandleScope handle_scope(isolate);
1191  Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed");
1192  Handle<String> source = String::NewFromUtf8(isolate, argv_[i + 1]);
1193  if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
1194  exception_was_thrown = true;
1195  break;
1196  }
1197  ++i;
1198  } else if (arg[0] == '-') {
1199  // Ignore other options. They have been parsed already.
1200  } else {
1201  // Use all other arguments as names of files to load and run.
1202  HandleScope handle_scope(isolate);
1203  Handle<String> file_name = String::NewFromUtf8(isolate, arg);
1204  Handle<String> source = ReadFile(isolate, arg);
1205  if (source.IsEmpty()) {
1206  printf("Error reading '%s'\n", arg);
1207  Shell::Exit(1);
1208  }
1209  if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
1210  exception_was_thrown = true;
1211  break;
1212  }
1213  }
1214  }
1215  if (exception_was_thrown != Shell::options.expected_to_throw) {
1216  Shell::Exit(1);
1217  }
1218 }
1219 
1220 
1222  int size;
1223  char* chars = ReadChars(isolate, name, &size);
1224  if (chars == NULL) return Handle<String>();
1225  Handle<String> result =
1227  delete[] chars;
1228  return result;
1229 }
1230 
1231 
1232 #ifndef V8_SHARED
1234  // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
1235  // which is not enough to parse the big literal expressions used in tests.
1236  // The stack size should be at least StackGuard::kLimitSize + some
1237  // OS-specific padding for thread startup code. 2Mbytes seems to be enough.
1238  return base::Thread::Options("IsolateThread", 2 * MB);
1239 }
1240 
1241 
1243  Isolate* isolate = Isolate::New();
1244  do {
1245  next_semaphore_.Wait();
1246  {
1247  Isolate::Scope iscope(isolate);
1248  {
1249  HandleScope scope(isolate);
1250  PerIsolateData data(isolate);
1252  {
1253  Context::Scope cscope(context);
1254  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1255  Execute(isolate);
1256  }
1257  }
1258  if (Shell::options.send_idle_notification) {
1259  const int kLongIdlePauseInMs = 1000;
1260  isolate->ContextDisposedNotification();
1261  isolate->IdleNotification(kLongIdlePauseInMs);
1262  }
1263  if (Shell::options.invoke_weak_callbacks) {
1264  // By sending a low memory notifications, we will try hard to collect
1265  // all garbage and will therefore also invoke all weak callbacks of
1266  // actually unreachable persistent handles.
1267  isolate->LowMemoryNotification();
1268  }
1269  }
1270  done_semaphore_.Signal();
1271  } while (!Shell::options.last_run);
1272 
1273  isolate->Dispose();
1274 }
1275 
1276 
1278  if (thread_ == NULL) {
1279  thread_ = new IsolateThread(this);
1280  thread_->Start();
1281  }
1282  next_semaphore_.Signal();
1283 }
1284 
1285 
1287  if (thread_ == NULL) return;
1288  if (Shell::options.last_run) {
1289  thread_->Join();
1290  } else {
1291  done_semaphore_.Wait();
1292  }
1293 }
1294 #endif // !V8_SHARED
1295 
1296 
1297 void SetFlagsFromString(const char* flags) {
1298  v8::V8::SetFlagsFromString(flags, static_cast<int>(strlen(flags)));
1299 }
1300 
1301 
1302 bool Shell::SetOptions(int argc, char* argv[]) {
1303  bool logfile_per_isolate = false;
1304  for (int i = 0; i < argc; i++) {
1305  if (strcmp(argv[i], "--stress-opt") == 0) {
1306  options.stress_opt = true;
1307  argv[i] = NULL;
1308  } else if (strcmp(argv[i], "--nostress-opt") == 0) {
1309  options.stress_opt = false;
1310  argv[i] = NULL;
1311  } else if (strcmp(argv[i], "--stress-deopt") == 0) {
1312  options.stress_deopt = true;
1313  argv[i] = NULL;
1314  } else if (strcmp(argv[i], "--mock-arraybuffer-allocator") == 0) {
1315  options.mock_arraybuffer_allocator = true;
1316  argv[i] = NULL;
1317  } else if (strcmp(argv[i], "--noalways-opt") == 0) {
1318  // No support for stressing if we can't use --always-opt.
1319  options.stress_opt = false;
1320  options.stress_deopt = false;
1321  } else if (strcmp(argv[i], "--logfile-per-isolate") == 0) {
1322  logfile_per_isolate = true;
1323  argv[i] = NULL;
1324  } else if (strcmp(argv[i], "--shell") == 0) {
1325  options.interactive_shell = true;
1326  argv[i] = NULL;
1327  } else if (strcmp(argv[i], "--test") == 0) {
1328  options.test_shell = true;
1329  argv[i] = NULL;
1330  } else if (strcmp(argv[i], "--send-idle-notification") == 0) {
1331  options.send_idle_notification = true;
1332  argv[i] = NULL;
1333  } else if (strcmp(argv[i], "--invoke-weak-callbacks") == 0) {
1334  options.invoke_weak_callbacks = true;
1335  // TODO(jochen) See issue 3351
1336  options.send_idle_notification = true;
1337  argv[i] = NULL;
1338  } else if (strcmp(argv[i], "-f") == 0) {
1339  // Ignore any -f flags for compatibility with other stand-alone
1340  // JavaScript engines.
1341  continue;
1342  } else if (strcmp(argv[i], "--isolate") == 0) {
1343 #ifdef V8_SHARED
1344  printf("D8 with shared library does not support multi-threading\n");
1345  return false;
1346 #endif // V8_SHARED
1347  options.num_isolates++;
1348  } else if (strcmp(argv[i], "--dump-heap-constants") == 0) {
1349 #ifdef V8_SHARED
1350  printf("D8 with shared library does not support constant dumping\n");
1351  return false;
1352 #else
1353  options.dump_heap_constants = true;
1354  argv[i] = NULL;
1355 #endif // V8_SHARED
1356  } else if (strcmp(argv[i], "--throws") == 0) {
1357  options.expected_to_throw = true;
1358  argv[i] = NULL;
1359  } else if (strncmp(argv[i], "--icu-data-file=", 16) == 0) {
1360  options.icu_data_file = argv[i] + 16;
1361  argv[i] = NULL;
1362 #ifdef V8_SHARED
1363  } else if (strcmp(argv[i], "--dump-counters") == 0) {
1364  printf("D8 with shared library does not include counters\n");
1365  return false;
1366  } else if (strcmp(argv[i], "--debugger") == 0) {
1367  printf("Javascript debugger not included\n");
1368  return false;
1369 #endif // V8_SHARED
1370 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
1371  } else if (strncmp(argv[i], "--natives_blob=", 15) == 0) {
1372  options.natives_blob = argv[i] + 15;
1373  argv[i] = NULL;
1374  } else if (strncmp(argv[i], "--snapshot_blob=", 16) == 0) {
1375  options.snapshot_blob = argv[i] + 16;
1376  argv[i] = NULL;
1377 #endif // V8_USE_EXTERNAL_STARTUP_DATA
1378  } else if (strcmp(argv[i], "--cache") == 0 ||
1379  strncmp(argv[i], "--cache=", 8) == 0) {
1380  const char* value = argv[i] + 7;
1381  if (!*value || strncmp(value, "=code", 6) == 0) {
1382  options.compile_options = v8::ScriptCompiler::kProduceCodeCache;
1383  } else if (strncmp(value, "=parse", 7) == 0) {
1384  options.compile_options = v8::ScriptCompiler::kProduceParserCache;
1385  } else if (strncmp(value, "=none", 6) == 0) {
1386  options.compile_options = v8::ScriptCompiler::kNoCompileOptions;
1387  } else {
1388  printf("Unknown option to --cache.\n");
1389  return false;
1390  }
1391  argv[i] = NULL;
1392  }
1393  }
1394 
1395  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
1396 
1397  // Set up isolated source groups.
1398  options.isolate_sources = new SourceGroup[options.num_isolates];
1399  SourceGroup* current = options.isolate_sources;
1400  current->Begin(argv, 1);
1401  for (int i = 1; i < argc; i++) {
1402  const char* str = argv[i];
1403  if (strcmp(str, "--isolate") == 0) {
1404  current->End(i);
1405  current++;
1406  current->Begin(argv, i + 1);
1407  } else if (strncmp(argv[i], "--", 2) == 0) {
1408  printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
1409  }
1410  }
1411  current->End(argc);
1412 
1413  if (!logfile_per_isolate && options.num_isolates) {
1414  SetFlagsFromString("--nologfile_per_isolate");
1415  }
1416 
1417  return true;
1418 }
1419 
1420 
1421 int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
1422 #ifndef V8_SHARED
1423  for (int i = 1; i < options.num_isolates; ++i) {
1424  options.isolate_sources[i].StartExecuteInThread();
1425  }
1426 #endif // !V8_SHARED
1427  {
1428  HandleScope scope(isolate);
1429  Local<Context> context = CreateEvaluationContext(isolate);
1430  if (options.last_run && options.use_interactive_shell()) {
1431  // Keep using the same context in the interactive shell.
1432  evaluation_context_.Reset(isolate, context);
1433 #ifndef V8_SHARED
1434  // If the interactive debugger is enabled make sure to activate
1435  // it before running the files passed on the command line.
1436  if (i::FLAG_debugger) {
1437  InstallUtilityScript(isolate);
1438  }
1439 #endif // !V8_SHARED
1440  }
1441  {
1442  Context::Scope cscope(context);
1443  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1444  options.isolate_sources[0].Execute(isolate);
1445  }
1446  }
1447  if (options.send_idle_notification) {
1448  const int kLongIdlePauseInMs = 1000;
1449  isolate->ContextDisposedNotification();
1450  isolate->IdleNotification(kLongIdlePauseInMs);
1451  }
1452  if (options.invoke_weak_callbacks) {
1453  // By sending a low memory notifications, we will try hard to collect all
1454  // garbage and will therefore also invoke all weak callbacks of actually
1455  // unreachable persistent handles.
1456  isolate->LowMemoryNotification();
1457  }
1458 
1459 #ifndef V8_SHARED
1460  for (int i = 1; i < options.num_isolates; ++i) {
1461  options.isolate_sources[i].WaitForThread();
1462  }
1463 #endif // !V8_SHARED
1464  return 0;
1465 }
1466 
1467 
1468 #ifndef V8_SHARED
1469 static void DumpHeapConstants(i::Isolate* isolate) {
1470  i::Heap* heap = isolate->heap();
1471 
1472  // Dump the INSTANCE_TYPES table to the console.
1473  printf("# List of known V8 instance types.\n");
1474 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T);
1475  printf("INSTANCE_TYPES = {\n");
1477  printf("}\n");
1478 #undef DUMP_TYPE
1479 
1480  // Dump the KNOWN_MAP table to the console.
1481  printf("\n# List of known V8 maps.\n");
1482 #define ROOT_LIST_CASE(type, name, camel_name) \
1483  if (n == NULL && o == heap->name()) n = #camel_name;
1484 #define STRUCT_LIST_CASE(upper_name, camel_name, name) \
1485  if (n == NULL && o == heap->name##_map()) n = #camel_name "Map";
1486  i::HeapObjectIterator it(heap->map_space());
1487  printf("KNOWN_MAPS = {\n");
1488  for (i::Object* o = it.Next(); o != NULL; o = it.Next()) {
1489  i::Map* m = i::Map::cast(o);
1490  const char* n = NULL;
1491  intptr_t p = reinterpret_cast<intptr_t>(m) & 0xfffff;
1492  int t = m->instance_type();
1495  if (n == NULL) continue;
1496  printf(" 0x%05" V8PRIxPTR ": (%d, \"%s\"),\n", p, t, n);
1497  }
1498  printf("}\n");
1499 #undef STRUCT_LIST_CASE
1500 #undef ROOT_LIST_CASE
1501 
1502  // Dump the KNOWN_OBJECTS table to the console.
1503  printf("\n# List of known V8 objects.\n");
1504 #define ROOT_LIST_CASE(type, name, camel_name) \
1505  if (n == NULL && o == heap->name()) n = #camel_name;
1506  i::OldSpaces spit(heap);
1507  printf("KNOWN_OBJECTS = {\n");
1508  for (i::PagedSpace* s = spit.next(); s != NULL; s = spit.next()) {
1509  i::HeapObjectIterator it(s);
1510  const char* sname = AllocationSpaceName(s->identity());
1511  for (i::Object* o = it.Next(); o != NULL; o = it.Next()) {
1512  const char* n = NULL;
1513  intptr_t p = reinterpret_cast<intptr_t>(o) & 0xfffff;
1515  if (n == NULL) continue;
1516  printf(" (\"%s\", 0x%05" V8PRIxPTR "): \"%s\",\n", sname, p, n);
1517  }
1518  }
1519  printf("}\n");
1520 #undef ROOT_LIST_CASE
1521 }
1522 #endif // !V8_SHARED
1523 
1524 
1526  public:
1527  virtual void* Allocate(size_t length) {
1528  void* data = AllocateUninitialized(length);
1529  return data == NULL ? data : memset(data, 0, length);
1530  }
1531  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
1532  virtual void Free(void* data, size_t) { free(data); }
1533 };
1534 
1535 
1537  public:
1538  virtual void* Allocate(size_t) OVERRIDE {
1539  return malloc(0);
1540  }
1541  virtual void* AllocateUninitialized(size_t length) OVERRIDE {
1542  return malloc(0);
1543  }
1544  virtual void Free(void* p, size_t) OVERRIDE {
1545  free(p);
1546  }
1547 };
1548 
1549 
1550 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
1551 class StartupDataHandler {
1552  public:
1553  StartupDataHandler(const char* natives_blob,
1554  const char* snapshot_blob) {
1555  Load(natives_blob, &natives_, v8::V8::SetNativesDataBlob);
1556  Load(snapshot_blob, &snapshot_, v8::V8::SetSnapshotDataBlob);
1557  }
1558 
1559  ~StartupDataHandler() {
1560  delete[] natives_.data;
1561  delete[] snapshot_.data;
1562  }
1563 
1564  private:
1565  void Load(const char* blob_file,
1566  v8::StartupData* startup_data,
1567  void (*setter_fn)(v8::StartupData*)) {
1568  startup_data->data = NULL;
1569  startup_data->compressed_size = 0;
1570  startup_data->raw_size = 0;
1571 
1572  if (!blob_file)
1573  return;
1574 
1575  FILE* file = fopen(blob_file, "rb");
1576  if (!file)
1577  return;
1578 
1579  fseek(file, 0, SEEK_END);
1580  startup_data->raw_size = ftell(file);
1581  rewind(file);
1582 
1583  startup_data->data = new char[startup_data->raw_size];
1584  startup_data->compressed_size = fread(
1585  const_cast<char*>(startup_data->data), 1, startup_data->raw_size,
1586  file);
1587  fclose(file);
1588 
1589  if (startup_data->raw_size == startup_data->compressed_size)
1590  (*setter_fn)(startup_data);
1591  }
1592 
1593  v8::StartupData natives_;
1594  v8::StartupData snapshot_;
1595 
1596  // Disallow copy & assign.
1597  StartupDataHandler(const StartupDataHandler& other);
1598  void operator=(const StartupDataHandler& other);
1599 };
1600 #endif // V8_USE_EXTERNAL_STARTUP_DATA
1601 
1602 
1603 int Shell::Main(int argc, char* argv[]) {
1604 #if (defined(_WIN32) || defined(_WIN64))
1605  UINT new_flags =
1606  SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
1607  UINT existing_flags = SetErrorMode(new_flags);
1608  SetErrorMode(existing_flags | new_flags);
1609 #if defined(_MSC_VER)
1610  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
1611  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
1612  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
1613  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
1614  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
1615  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
1616  _set_error_mode(_OUT_TO_STDERR);
1617 #endif // defined(_MSC_VER)
1618 #endif // defined(_WIN32) || defined(_WIN64)
1619  if (!SetOptions(argc, argv)) return 1;
1620  v8::V8::InitializeICU(options.icu_data_file);
1622  v8::V8::InitializePlatform(platform);
1624 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
1625  StartupDataHandler startup_data(options.natives_blob, options.snapshot_blob);
1626 #endif
1627  SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg");
1628  SetFlagsFromString("--redirect-code-traces-to=code.asm");
1629  ShellArrayBufferAllocator array_buffer_allocator;
1630  MockArrayBufferAllocator mock_arraybuffer_allocator;
1631  if (options.mock_arraybuffer_allocator) {
1632  v8::V8::SetArrayBufferAllocator(&mock_arraybuffer_allocator);
1633  } else {
1634  v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
1635  }
1636  int result = 0;
1637  Isolate::CreateParams create_params;
1638 #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE)
1639  if (i::FLAG_gdbjit) {
1640  create_params.code_event_handler = i::GDBJITInterface::EventHandler;
1641  }
1642 #endif
1643 #ifdef ENABLE_VTUNE_JIT_INTERFACE
1644  vTune::InitializeVtuneForV8(create_params);
1645 #endif
1646 #ifndef V8_SHARED
1647  create_params.constraints.ConfigureDefaults(
1648  base::SysInfo::AmountOfPhysicalMemory(),
1649  base::SysInfo::AmountOfVirtualMemory(),
1650  base::SysInfo::NumberOfProcessors());
1651 #endif
1652  Isolate* isolate = Isolate::New(create_params);
1653  DumbLineEditor dumb_line_editor(isolate);
1654  {
1655  Isolate::Scope scope(isolate);
1656  Initialize(isolate);
1657  PerIsolateData data(isolate);
1658  InitializeDebugger(isolate);
1659 
1660 #ifndef V8_SHARED
1661  if (options.dump_heap_constants) {
1662  DumpHeapConstants(reinterpret_cast<i::Isolate*>(isolate));
1663  return 0;
1664  }
1665 #endif
1666 
1667  if (options.stress_opt || options.stress_deopt) {
1668  Testing::SetStressRunType(options.stress_opt
1671  int stress_runs = Testing::GetStressRuns();
1672  for (int i = 0; i < stress_runs && result == 0; i++) {
1673  printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
1675  options.last_run = (i == stress_runs - 1);
1676  result = RunMain(isolate, argc, argv);
1677  }
1678  printf("======== Full Deoptimization =======\n");
1680 #if !defined(V8_SHARED)
1681  } else if (i::FLAG_stress_runs > 0) {
1682  int stress_runs = i::FLAG_stress_runs;
1683  for (int i = 0; i < stress_runs && result == 0; i++) {
1684  printf("============ Run %d/%d ============\n", i + 1, stress_runs);
1685  options.last_run = (i == stress_runs - 1);
1686  result = RunMain(isolate, argc, argv);
1687  }
1688 #endif
1689  } else {
1690  result = RunMain(isolate, argc, argv);
1691  }
1692 
1693  // Run interactive shell if explicitly requested or if no script has been
1694  // executed, but never on --test
1695  if (options.use_interactive_shell()) {
1696 #ifndef V8_SHARED
1697  if (!i::FLAG_debugger) {
1698  InstallUtilityScript(isolate);
1699  }
1700 #endif // !V8_SHARED
1701  RunShell(isolate);
1702  }
1703  }
1704 #ifndef V8_SHARED
1705  // Dump basic block profiling data.
1707  reinterpret_cast<i::Isolate*>(isolate)->basic_block_profiler()) {
1708  i::OFStream os(stdout);
1709  os << *profiler;
1710  }
1711 #endif // !V8_SHARED
1712  isolate->Dispose();
1713  V8::Dispose();
1715  delete platform;
1716 
1717  OnExit();
1718 
1719  return result;
1720 }
1721 
1722 } // namespace v8
1723 
1724 
1725 #ifndef GOOGLE3
1726 int main(int argc, char* argv[]) {
1727  return v8::Shell::Main(argc, argv);
1728 }
1729 #endif
Allocator that V8 uses to allocate |ArrayBuffer|'s memory.
Definition: v8.h:2859
static Local< ArrayBuffer > New(Isolate *isolate, size_t byte_length)
Create a new ArrayBuffer.
Definition: api.cc:6024
Stack-allocated class which sets the execution context for all operations executed within a local sco...
Definition: v8.h:5579
static Local< Context > New(Isolate *isolate, ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Creates a new context and returns a handle to the newly allocated context.
Definition: api.cc:5217
Counter * GetNextCounter()
Definition: d8.cc:713
static int Hash(const char *name)
Definition: d8.cc:735
static bool Match(void *key1, void *key2)
Definition: d8.cc:166
Definition: d8.h:23
int32_t * Bind(const char *name, bool histogram)
Definition: d8.cc:689
static const int kMaxNameSize
Definition: d8.h:25
int32_t sample_total()
Definition: d8.h:29
int32_t * ptr()
Definition: d8.h:27
int32_t count()
Definition: d8.h:28
bool is_histogram()
Definition: d8.h:30
void AddSample(int32_t sample)
Definition: d8.cc:699
static bool SetDebugEventListener(EventCallback that, Handle< Value > data=Handle< Value >())
Definition: api.cc:6917
virtual Handle< String > Prompt(const char *prompt)
Definition: d8.cc:136
DumbLineEditor(Isolate *isolate)
Definition: d8.cc:128
Isolate * isolate_
Definition: d8.cc:132
A HandleScope which first allocates a handle in the current scope which will be later filled with the...
Definition: v8.h:855
Local< T > Escape(Local< T > value)
Pushes the value into the previous scope and returns a handle to it.
Definition: v8.h:865
The argument information given to function call callbacks.
Definition: v8.h:2650
ReturnValue< T > GetReturnValue() const
Definition: v8.h:6348
Isolate * GetIsolate() const
Definition: v8.h:6342
int Length() const
Definition: v8.h:6360
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >(), int length=0)
Creates a function template.
Definition: api.cc:904
A stack-allocated class that governs a number of local handles.
Definition: v8.h:802
An object reference managed by the v8 garbage collector.
Definition: v8.h:198
bool IsEmpty() const
Returns true if the handle is empty.
Definition: v8.h:228
static Handle< T > Cast(Handle< S > that)
Definition: v8.h:277
Stack-allocated class which sets the isolate for all operations executed within a local scope.
Definition: v8.h:4398
Isolate represents an isolated instance of the V8 engine.
Definition: v8.h:4356
Local< Context > GetEnteredContext()
Returns the last entered context.
Definition: api.cc:6402
int ContextDisposedNotification()
Optional notification that a context has been disposed.
Definition: api.cc:6807
void Dispose()
Disposes the isolate.
Definition: api.cc:6609
void SetData(uint32_t slot, void *data)
Associate embedder-specific data with the isolate.
Definition: v8.h:6872
static Isolate * New(const CreateParams &params=CreateParams())
Creates a new isolate.
Definition: api.cc:6583
int64_t AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)
Adjusts the amount of registered external memory.
Definition: v8.h:6890
void LowMemoryNotification()
Optional notification that the system is running low on memory.
Definition: api.cc:6797
void SetCounterFunction(CounterLookupCallback)
Enables the host application to provide a mechanism for recording statistics counters.
Definition: api.cc:6764
Local< Value > ThrowException(Local< Value > exception)
Schedules an exception to be thrown when returning to JavaScript.
Definition: api.cc:6411
void SetAddHistogramSampleFunction(AddHistogramSampleCallback)
Definition: api.cc:6780
bool IdleNotification(int idle_time_in_ms)
Optional notification that the embedder is idle.
Definition: api.cc:6788
void * GetData(uint32_t slot)
Retrieve embedder-specific data from the isolate.
Definition: v8.h:6878
bool InContext()
Returns true if this isolate has a current context.
Definition: api.cc:6378
void SetCreateHistogramFunction(CreateHistogramCallback)
Enables the host application to provide a mechanism for recording histograms.
Definition: api.cc:6772
virtual bool Close()
Definition: d8.h:105
virtual Handle< String > Prompt(const char *prompt)=0
const char * name()
Definition: d8.h:108
static LineEditor * Get()
Definition: d8.h:109
virtual bool Open(Isolate *isolate)
Definition: d8.h:104
@ DUMB
Definition: d8.h:99
Type type_
Definition: d8.h:111
static LineEditor * current_
Definition: d8.h:113
LineEditor(Type type, const char *name)
Definition: d8.cc:120
A light-weight stack-allocated object handle.
Definition: v8.h:334
static Local< T > Cast(Local< S > that)
Definition: v8.h:348
static Local< T > New(Isolate *isolate, Handle< T > that)
Create a local handle for the content of another handle.
Definition: v8.h:5987
virtual void Free(void *p, size_t) OVERRIDE
Free the memory block of size |length|, pointed to by |data|.
Definition: d8.cc:1544
virtual void * AllocateUninitialized(size_t length) OVERRIDE
Allocate |length| bytes.
Definition: d8.cc:1541
virtual void * Allocate(size_t) OVERRIDE
Allocate |length| bytes.
Definition: d8.cc:1538
static Local< ObjectTemplate > New()
Definition: api.cc:1244
RealmScope(PerIsolateData *data)
Definition: d8.cc:287
PerIsolateData * data_
Definition: d8.cc:98
int RealmFind(Handle< Context > context)
Definition: d8.cc:307
~PerIsolateData()
Definition: d8.cc:85
int RealmIndexOrThrow(const v8::FunctionCallbackInfo< v8::Value > &args, int arg_offset)
Definition: d8.cc:315
Isolate * isolate_
Definition: d8.cc:104
int realm_current_
Definition: d8.cc:106
int realm_switch_
Definition: d8.cc:107
PerIsolateData(Isolate *isolate)
Definition: d8.cc:80
int realm_count_
Definition: d8.cc:105
Persistent< Context > * realms_
Definition: d8.cc:108
Persistent< Value > realm_shared_
Definition: d8.cc:109
static PerIsolateData * Get(Isolate *isolate)
Definition: d8.cc:89
A PersistentBase which allows copy and assignment.
Definition: v8.h:627
V8 Platform abstraction layer.
Definition: v8-platform.h:28
The information passed to a property callback about the context of the property access.
Definition: v8.h:2691
ReturnValue< T > GetReturnValue() const
Definition: v8.h:6831
Isolate * GetIsolate() const
Definition: v8.h:6807
void ConfigureDefaults(uint64_t physical_memory, uint64_t virtual_memory_limit, uint32_t number_of_processors)
Configures the constraints with reasonable default values based on the capabilities of the current de...
Definition: api.cc:429
Source code which can be then compiled to a UnboundScript or Script.
Definition: v8.h:1058
const CachedData * GetCachedData() const
Definition: v8.h:6410
@ kProduceParserCache
Definition: v8.h:1161
@ kConsumeParserCache
Definition: v8.h:1162
@ kProduceCodeCache
Definition: v8.h:1163
@ kNoCompileOptions
Definition: v8.h:1160
@ kConsumeCodeCache
Definition: v8.h:1164
static Local< UnboundScript > CompileUnbound(Isolate *isolate, Source *source, CompileOptions options=kNoCompileOptions)
Compiles the specified script (context-independent).
Definition: api.cc:1703
The origin, within a file, of a script.
Definition: v8.h:922
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL)
A shorthand for ScriptCompiler::Compile().
Definition: api.cc:1880
virtual void * AllocateUninitialized(size_t length)
Allocate |length| bytes.
Definition: d8.cc:1531
virtual void Free(void *data, size_t)
Free the memory block of size |length|, pointed to by |data|.
Definition: d8.cc:1532
virtual void * Allocate(size_t length)
Allocate |length| bytes.
Definition: d8.cc:1527
bool script_executed
Definition: d8.h:225
v8::ScriptCompiler::CompileOptions compile_options
Definition: d8.h:237
bool test_shell
Definition: d8.h:232
Definition: d8.h:247
static int Main(int argc, char *argv[])
Definition: d8.cc:1603
static void Read(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:501
static Local< UnboundScript > CompileString(Isolate *isolate, Local< String > source, Local< Value > name, v8::ScriptCompiler::CompileOptions compile_options)
Definition: d8.cc:181
static CounterCollection * counters_
Definition: d8.h:375
static void AddHistogramSample(void *histogram, int sample)
Definition: d8.cc:781
static base::OS::MemoryMappedFile * counters_file_
Definition: d8.h:376
static void Quit(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:574
static void RealmSharedGet(Local< String > property, const PropertyCallbackInfo< Value > &info)
Definition: d8.cc:452
static void PerformanceNow(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:337
static void RealmEval(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:430
static Persistent< Context > utility_context_
Definition: d8.h:370
static void RealmCreate(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:387
static void ReadBuffer(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:1115
static Handle< Array > GetCompletions(Isolate *isolate, Handle< String > text, Handle< String > full)
Definition: d8.cc:638
static void ReportException(Isolate *isolate, TryCatch *try_catch)
Definition: d8.cc:587
static const char * ToCString(const v8::String::Utf8Value &value)
Definition: d8.cc:175
static Local< Object > DebugMessageDetails(Isolate *isolate, Handle< String > message)
Definition: d8.cc:657
static void * CreateHistogram(const char *name, int min, int max, size_t buckets)
Definition: d8.cc:773
static void Version(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:581
static void Print(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:469
static void InstallUtilityScript(Isolate *isolate)
Definition: d8.cc:787
static Local< Context > CreateEvaluationContext(Isolate *isolate)
Definition: d8.cc:960
static const char * kPrompt
Definition: d8.h:364
static void RealmSharedSet(Local< String > property, Local< Value > value, const PropertyCallbackInfo< void > &info)
Definition: d8.cc:460
static void RealmDispose(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:405
static void Initialize(Isolate *isolate)
Definition: d8.cc:925
static void RunShell(Isolate *isolate)
Definition: d8.cc:1156
static int RunMain(Isolate *isolate, int argc, char *argv[])
Definition: d8.cc:1421
static base::Mutex context_mutex_
Definition: d8.h:377
static const base::TimeTicks kInitialTicks
Definition: d8.h:378
static Counter * GetCounter(const char *name, bool is_histogram)
Definition: d8.cc:746
static void RealmCurrent(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:352
static void RealmOwner(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:362
static bool SetOptions(int argc, char *argv[])
Definition: d8.cc:1302
static void Exit(int exit_code)
Definition: d8.cc:991
static Local< Value > DebugCommandToJSONRequest(Isolate *isolate, Handle< String > command)
Definition: d8.cc:673
static int * LookupCounter(const char *name)
Definition: d8.cc:762
static void RealmSwitch(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:420
static void Load(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:549
static void OnExit()
Definition: d8.cc:1013
static CounterCollection local_counters_
Definition: d8.h:374
static Handle< String > ReadFromStdin(Isolate *isolate)
Definition: d8.cc:516
static CounterMap * counter_map_
Definition: d8.h:371
static void RealmGlobal(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:377
static Handle< String > ReadFile(Isolate *isolate, const char *name)
Definition: d8.cc:1145
static void InitializeDebugger(Isolate *isolate)
Definition: d8.cc:949
static bool ExecuteString(Isolate *isolate, Handle< String > source, Handle< Value > name, bool print_result, bool report_exceptions)
Definition: d8.cc:211
static Handle< ObjectTemplate > CreateGlobalTemplate(Isolate *isolate)
Definition: d8.cc:870
static Persistent< Context > evaluation_context_
Definition: d8.h:368
static ShellOptions options
Definition: d8.h:365
static void MapCounters(v8::Isolate *isolate, const char *name)
Definition: d8.cc:719
static void Write(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:476
void Begin(char **argv, int offset)
Definition: d8.h:131
static base::Thread::Options GetThreadOptions()
Definition: d8.cc:1233
void Execute(Isolate *isolate)
Definition: d8.cc:1184
void End(int offset)
Definition: d8.h:136
void StartExecuteInThread()
Definition: d8.cc:1277
void WaitForThread()
Definition: d8.cc:1286
~SourceGroup()
Definition: d8.cc:1176
Handle< String > ReadFile(Isolate *isolate, const char *name)
Definition: d8.cc:1221
void ExecuteInThread()
Definition: d8.cc:1242
A helper class for driving V8 startup data decompression.
Definition: v8.h:4899
int raw_size
Definition: v8.h:4887
int compressed_size
Definition: v8.h:4886
const char * data
Definition: v8.h:4885
Converts an object to a UTF-8-encoded character array.
Definition: v8.h:2048
int length() const
Definition: v8.h:2054
@ kNormalString
Definition: v8.h:1963
static Local< String > Concat(Handle< String > left, Handle< String > right)
Creates a new string by concatenating the left and the right strings passed in as parameters.
Definition: api.cc:5486
static Local< String > NewFromUtf8(Isolate *isolate, const char *data, NewStringType type=kNormalString, int length=-1)
Allocates a new string from UTF-8 data.
Definition: api.cc:5447
@ kStressTypeDeopt
Definition: v8-testing.h:19
@ kStressTypeOpt
Definition: v8-testing.h:18
static int GetStressRuns()
Get the number of runs of a given test that is required to get the full stress coverage.
Definition: api.cc:7461
static void DeoptimizeAll()
Force deoptimization of all functions.
Definition: api.cc:7514
static void PrepareStressRun(int run)
Indicate the number of the run which is about to start.
Definition: api.cc:7478
static void SetStressRunType(StressType type)
Set the type of stressing to do.
Definition: api.cc:7456
An external exception handler.
Definition: v8.h:5271
void SetVerbose(bool value)
Set verbosity of the external exception handler.
Definition: api.cc:2046
Local< v8::Message > Message() const
Returns the message associated with this exception.
Definition: api.cc:2012
Local< Value > Exception() const
Returns the exception caught by this try/catch block.
Definition: api.cc:1976
Handle< Value > ReThrow()
Throws the exception caught by this TryCatch in a way that avoids it being caught again by this same ...
Definition: api.cc:1969
Local< Value > StackTrace() const
Returns the .stack property of the thrown object.
Definition: api.cc:1988
bool HasCaught() const
Returns true if an exception has been caught by this try/catch block.
Definition: api.cc:1954
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition: api.h:288
static bool InitializeICU(const char *icu_data_file=NULL)
Initialize the ICU library bundled with V8.
Definition: api.cc:5141
static const char * GetVersion()
Get the version string.
Definition: api.cc:5146
static StartupData::CompressionAlgorithm GetCompressedStartupDataAlgorithm()
The following 4 functions are to be used when V8 is built with the 'compress_startup_data' flag enabl...
Definition: api.cc:246
static void SetFlagsFromString(const char *str, int length)
Sets V8 flags from a string.
Definition: api.cc:364
static void InitializePlatform(Platform *platform)
Sets the v8::Platform to use.
Definition: api.cc:5048
static void SetSnapshotDataBlob(StartupData *startup_blob)
Definition: api.cc:342
static void SetFlagsFromCommandLine(int *argc, char **argv, bool remove_flags)
Sets V8 flags from the command line.
Definition: api.cc:369
static void SetArrayBufferAllocator(ArrayBuffer::Allocator *allocator)
Set allocator to use for ArrayBuffer memory.
Definition: api.cc:5074
static void SetNativesDataBlob(StartupData *startup_blob)
Hand startup data to V8, in case the embedder has chosen to build V8 with external startup data.
Definition: api.cc:333
static void ShutdownPlatform()
Clears all references to the v8::Platform.
Definition: api.cc:5053
static bool Dispose()
Releases any resources used by v8 and stops any utility threads that may be running.
Definition: api.cc:5084
static bool Initialize()
Initializes V8.
Definition: api.cc:5058
Isolate * GetIsolate() const
Definition: v8.h:421
P * GetParameter() const
Definition: v8.h:423
Local< T > GetValue() const
Definition: v8.h:422
static MemoryMappedFile * create(const char *name, int size, void *initial)
Handle< Context > debug_context()
Definition: debug.h:459
double synthetic_time()
Definition: heap.h:943
MapSpace * map_space()
Definition: heap.h:597
InstanceType instance_type()
Definition: objects-inl.h:4323
static Vector< const char > GetScriptName(int index)
static Vector< const char > GetRawScriptSource(int index)
static int GetIndex(const char *name)
static Smi * FromInt(int value)
Definition: objects-inl.h:1321
T * start() const
Definition: vector.h:47
int length() const
Definition: vector.h:41
#define OVERRIDE
int main(int argc, char *argv[])
Definition: d8.cc:1726
#define ROOT_LIST_CASE(type, name, camel_name)
#define DUMP_TYPE(T)
#define DCHECK(condition)
Definition: d8.cc:66
#define STRUCT_LIST_CASE(upper_name, camel_name, name)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob Print the time it takes to lazily compile hydrogen code stubs dump only objects containing this substring stress the GC compactor to flush out pretty print source code for builtins print C code to recreate TurboFan graphs report heap spill statistics along with enable possessive quantifier syntax for testing Minimal Log code events to the log file without profiling log positions Log statistical profiling Used with turns on browser compatible mode for profiling Enable perf linux profiler(experimental annotate support).") DEFINE_STRING(gc_fake_mmap
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob file(mksnapshot only)") DEFINE_BOOL(profile_hydrogen_code_stub_compilation
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define ROOT_LIST(V)
Definition: heap.h:206
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
#define V8PRIxPTR
Definition: macros.h:363
int int32_t
Definition: unicode.cc:24
Vector< const char > CStrVector(const char *data)
Definition: vector.h:158
char * ReadLine(const char *prompt)
Definition: utils.cc:129
static int min(int a, int b)
Definition: liveedit.cc:273
Vector< const char > ReadFile(const char *filename, bool *exists, bool verbose)
Definition: utils.cc:241
int StrLength(const char *string)
Definition: vector.h:147
const char * AllocationSpaceName(AllocationSpace space)
v8::Platform * CreateDefaultPlatform(int thread_pool_size)
Returns a new instance of the default v8::Platform implementation.
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
static void SetFlagsFromString(const char *flags)
Definition: api.cc:7473
bool operator<(const CounterAndKey &lhs, const CounterAndKey &rhs)
Definition: d8.cc:1007
static void DumpHeapConstants(i::Isolate *isolate)
Definition: d8.cc:1469
static void ReadBufferWeakCallback(const v8::WeakCallbackData< ArrayBuffer, DataAndPersistent > &data)
Definition: d8.cc:1103
void HandleDebugEvent(const Debug::EventDetails &event_details)
Definition: d8-debug.cc:17
static char * ReadChars(Isolate *isolate, const char *name, int *size_out)
Definition: d8.cc:1077
static Handle< Value > Throw(Isolate *isolate, const char *message)
Definition: d8.cc:72
static FILE * FOpen(const char *path, const char *mode)
Definition: d8.cc:1056
Handle< Primitive > Undefined(Isolate *isolate)
Definition: v8.h:6836
const int MB
Definition: d8.cc:164
void InitializeVtuneForV8(v8::Isolate::CreateParams &params)
Definition: vtune-jit.cc:274
#define INSTANCE_TYPE_LIST(V)
Definition: objects.h:339
#define STRUCT_LIST(V)
Definition: objects.h:515
Counter * counter
Definition: d8.cc:1002
const char * key
Definition: d8.cc:1003
uint8_t * data
Definition: d8.cc:1098
Persistent< ArrayBuffer > handle
Definition: d8.cc:1099
Initial configuration parameters for a new Isolate.
Definition: v8.h:4361
ResourceConstraints constraints
ResourceConstraints to use for the new Isolate.
Definition: v8.h:4385
JitCodeEventHandler code_event_handler
Allows the host application to provide the address of a function that is notified each time code is a...
Definition: v8.h:4380
Compilation data that the embedder can cache and pass back to speed up future compilations.
Definition: v8.h:1028
const uint8_t * data
Definition: v8.h:1045