v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
d8.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 
29 // Defined when linking against shared lib on Windows.
30 #if defined(USING_V8_SHARED) && !defined(V8_SHARED)
31 #define V8_SHARED
32 #endif
33 
34 #ifdef COMPRESS_STARTUP_DATA_BZ2
35 #include <bzlib.h>
36 #endif
37 
38 #include <errno.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/stat.h>
42 
43 #ifdef V8_SHARED
44 #include <assert.h>
45 #endif // V8_SHARED
46 
47 #ifndef V8_SHARED
48 #include <algorithm>
49 #endif // !V8_SHARED
50 
51 #ifdef V8_SHARED
52 #include "../include/v8-testing.h"
53 #endif // V8_SHARED
54 
55 #ifdef ENABLE_VTUNE_JIT_INTERFACE
56 #include "third_party/vtune/v8-vtune.h"
57 #endif
58 
59 #include "d8.h"
60 
61 #ifndef V8_SHARED
62 #include "api.h"
63 #include "checks.h"
64 #include "cpu.h"
65 #include "d8-debug.h"
66 #include "debug.h"
67 #include "natives.h"
68 #include "platform.h"
69 #include "v8.h"
70 #endif // V8_SHARED
71 
72 #if !defined(_WIN32) && !defined(_WIN64)
73 #include <unistd.h> // NOLINT
74 #endif
75 
76 #ifndef ASSERT
77 #define ASSERT(condition) assert(condition)
78 #endif
79 
80 namespace v8 {
81 
82 
83 static Handle<Value> Throw(Isolate* isolate, const char* message) {
84  return isolate->ThrowException(String::NewFromUtf8(isolate, message));
85 }
86 
87 
88 
90  public:
91  explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) {
92  HandleScope scope(isolate);
93  isolate->SetData(0, this);
94  }
95 
97  isolate_->SetData(0, NULL); // Not really needed, just to be sure...
98  }
99 
100  inline static PerIsolateData* Get(Isolate* isolate) {
101  return reinterpret_cast<PerIsolateData*>(isolate->GetData(0));
102  }
103 
104  class RealmScope {
105  public:
106  explicit RealmScope(PerIsolateData* data);
107  ~RealmScope();
108  private:
109  PerIsolateData* data_;
110  };
111 
112  private:
113  friend class Shell;
114  friend class RealmScope;
115  Isolate* isolate_;
116  int realm_count_;
117  int realm_current_;
118  int realm_switch_;
119  Persistent<Context>* realms_;
120  Persistent<Value> realm_shared_;
121 
122  int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
123  int arg_offset);
124  int RealmFind(Handle<Context> context);
125 };
126 
127 
129 
130 
131 LineEditor::LineEditor(Type type, const char* name)
132  : type_(type), name_(name) {
133  if (current_ == NULL || current_->type_ < type) current_ = this;
134 }
135 
136 
137 class DumbLineEditor: public LineEditor {
138  public:
139  explicit DumbLineEditor(Isolate* isolate)
140  : LineEditor(LineEditor::DUMB, "dumb"), isolate_(isolate) { }
141  virtual Handle<String> Prompt(const char* prompt);
142  private:
143  Isolate* isolate_;
144 };
145 
146 
148  printf("%s", prompt);
149 #if defined(__native_client__)
150  // Native Client libc is used to being embedded in Chrome and
151  // has trouble recognizing when to flush.
152  fflush(stdout);
153 #endif
154  return Shell::ReadFromStdin(isolate_);
155 }
156 
157 
158 #ifndef V8_SHARED
159 CounterMap* Shell::counter_map_;
160 i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
161 CounterCollection Shell::local_counters_;
162 CounterCollection* Shell::counters_ = &local_counters_;
163 i::Mutex Shell::context_mutex_;
164 const i::TimeTicks Shell::kInitialTicks = i::TimeTicks::HighResolutionNow();
165 Persistent<Context> Shell::utility_context_;
166 #endif // V8_SHARED
167 
168 Persistent<Context> Shell::evaluation_context_;
170 const char* Shell::kPrompt = "d8> ";
171 
172 
173 #ifndef V8_SHARED
174 const int MB = 1024 * 1024;
175 
176 bool CounterMap::Match(void* key1, void* key2) {
177  const char* name1 = reinterpret_cast<const char*>(key1);
178  const char* name2 = reinterpret_cast<const char*>(key2);
179  return strcmp(name1, name2) == 0;
180 }
181 #endif // V8_SHARED
182 
183 
184 // Converts a V8 value to a C string.
185 const char* Shell::ToCString(const v8::String::Utf8Value& value) {
186  return *value ? *value : "<string conversion failed>";
187 }
188 
189 
190 // Executes a string within the current v8 context.
192  Handle<String> source,
194  bool print_result,
195  bool report_exceptions) {
196 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
197  bool FLAG_debugger = i::FLAG_debugger;
198 #else
199  bool FLAG_debugger = false;
200 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
201  HandleScope handle_scope(isolate);
202  TryCatch try_catch;
203  options.script_executed = true;
204  if (FLAG_debugger) {
205  // When debugging make exceptions appear to be uncaught.
206  try_catch.SetVerbose(true);
207  }
208  ScriptOrigin origin(name);
209  ScriptCompiler::Source script_source(source, origin);
210  Handle<UnboundScript> script =
211  ScriptCompiler::CompileUnbound(isolate, &script_source);
212  if (script.IsEmpty()) {
213  // Print errors that happened during compilation.
214  if (report_exceptions && !FLAG_debugger)
215  ReportException(isolate, &try_catch);
216  return false;
217  } else {
218  PerIsolateData* data = PerIsolateData::Get(isolate);
219  Local<Context> realm =
220  Local<Context>::New(isolate, data->realms_[data->realm_current_]);
221  realm->Enter();
222  Handle<Value> result = script->BindToCurrentContext()->Run();
223  realm->Exit();
224  data->realm_current_ = data->realm_switch_;
225  if (result.IsEmpty()) {
226  ASSERT(try_catch.HasCaught());
227  // Print errors that happened during execution.
228  if (report_exceptions && !FLAG_debugger)
229  ReportException(isolate, &try_catch);
230  return false;
231  } else {
232  ASSERT(!try_catch.HasCaught());
233  if (print_result) {
234 #if !defined(V8_SHARED)
235  if (options.test_shell) {
236 #endif
237  if (!result->IsUndefined()) {
238  // If all went well and the result wasn't undefined then print
239  // the returned value.
240  v8::String::Utf8Value str(result);
241  fwrite(*str, sizeof(**str), str.length(), stdout);
242  printf("\n");
243  }
244 #if !defined(V8_SHARED)
245  } else {
246  v8::TryCatch try_catch;
247  v8::Local<v8::Context> context =
248  v8::Local<v8::Context>::New(isolate, utility_context_);
249  v8::Context::Scope context_scope(context);
250  Handle<Object> global = context->Global();
251  Handle<Value> fun =
252  global->Get(String::NewFromUtf8(isolate, "Stringify"));
253  Handle<Value> argv[1] = { result };
254  Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
255  if (try_catch.HasCaught()) return true;
256  v8::String::Utf8Value str(s);
257  fwrite(*str, sizeof(**str), str.length(), stdout);
258  printf("\n");
259  }
260 #endif
261  }
262  return true;
263  }
264  }
265 }
266 
267 
269  data_->realm_count_ = 1;
270  data_->realm_current_ = 0;
271  data_->realm_switch_ = 0;
272  data_->realms_ = new Persistent<Context>[1];
273  data_->realms_[0].Reset(data_->isolate_,
274  data_->isolate_->GetEnteredContext());
275 }
276 
277 
279  // Drop realms to avoid keeping them alive.
280  for (int i = 0; i < data_->realm_count_; ++i)
281  data_->realms_[i].Reset();
282  delete[] data_->realms_;
283  if (!data_->realm_shared_.IsEmpty())
284  data_->realm_shared_.Reset();
285 }
286 
287 
288 int PerIsolateData::RealmFind(Handle<Context> context) {
289  for (int i = 0; i < realm_count_; ++i) {
290  if (realms_[i] == context) return i;
291  }
292  return -1;
293 }
294 
295 
296 int PerIsolateData::RealmIndexOrThrow(
298  int arg_offset) {
299  if (args.Length() < arg_offset || !args[arg_offset]->IsNumber()) {
300  Throw(args.GetIsolate(), "Invalid argument");
301  return -1;
302  }
303  int index = args[arg_offset]->Int32Value();
304  if (index < 0 ||
305  index >= realm_count_ ||
306  realms_[index].IsEmpty()) {
307  Throw(args.GetIsolate(), "Invalid realm index");
308  return -1;
309  }
310  return index;
311 }
312 
313 
314 #ifndef V8_SHARED
315 // performance.now() returns a time stamp as double, measured in milliseconds.
317  i::TimeDelta delta = i::TimeTicks::HighResolutionNow() - kInitialTicks;
318  args.GetReturnValue().Set(delta.InMillisecondsF());
319 }
320 #endif // V8_SHARED
321 
322 
323 // Realm.current() returns the index of the currently active realm.
325  Isolate* isolate = args.GetIsolate();
326  PerIsolateData* data = PerIsolateData::Get(isolate);
327  int index = data->RealmFind(isolate->GetEnteredContext());
328  if (index == -1) return;
329  args.GetReturnValue().Set(index);
330 }
331 
332 
333 // Realm.owner(o) returns the index of the realm that created o.
335  Isolate* isolate = args.GetIsolate();
336  PerIsolateData* data = PerIsolateData::Get(isolate);
337  if (args.Length() < 1 || !args[0]->IsObject()) {
338  Throw(args.GetIsolate(), "Invalid argument");
339  return;
340  }
341  int index = data->RealmFind(args[0]->ToObject()->CreationContext());
342  if (index == -1) return;
343  args.GetReturnValue().Set(index);
344 }
345 
346 
347 // Realm.global(i) returns the global object of realm i.
348 // (Note that properties of global objects cannot be read/written cross-realm.)
351  int index = data->RealmIndexOrThrow(args, 0);
352  if (index == -1) return;
353  args.GetReturnValue().Set(
354  Local<Context>::New(args.GetIsolate(), data->realms_[index])->Global());
355 }
356 
357 
358 // Realm.create() creates a new realm and returns its index.
360  Isolate* isolate = args.GetIsolate();
361  PerIsolateData* data = PerIsolateData::Get(isolate);
362  Persistent<Context>* old_realms = data->realms_;
363  int index = data->realm_count_;
364  data->realms_ = new Persistent<Context>[++data->realm_count_];
365  for (int i = 0; i < index; ++i) {
366  data->realms_[i].Reset(isolate, old_realms[i]);
367  }
368  delete[] old_realms;
369  Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
370  data->realms_[index].Reset(
371  isolate, Context::New(isolate, NULL, global_template));
372  args.GetReturnValue().Set(index);
373 }
374 
375 
376 // Realm.dispose(i) disposes the reference to the realm i.
378  Isolate* isolate = args.GetIsolate();
379  PerIsolateData* data = PerIsolateData::Get(isolate);
380  int index = data->RealmIndexOrThrow(args, 0);
381  if (index == -1) return;
382  if (index == 0 ||
383  index == data->realm_current_ || index == data->realm_switch_) {
384  Throw(args.GetIsolate(), "Invalid realm index");
385  return;
386  }
387  data->realms_[index].Reset();
388 }
389 
390 
391 // Realm.switch(i) switches to the realm i for consecutive interactive inputs.
393  Isolate* isolate = args.GetIsolate();
394  PerIsolateData* data = PerIsolateData::Get(isolate);
395  int index = data->RealmIndexOrThrow(args, 0);
396  if (index == -1) return;
397  data->realm_switch_ = index;
398 }
399 
400 
401 // Realm.eval(i, s) evaluates s in realm i and returns the result.
403  Isolate* isolate = args.GetIsolate();
404  PerIsolateData* data = PerIsolateData::Get(isolate);
405  int index = data->RealmIndexOrThrow(args, 0);
406  if (index == -1) return;
407  if (args.Length() < 2 || !args[1]->IsString()) {
408  Throw(args.GetIsolate(), "Invalid argument");
409  return;
410  }
411  ScriptCompiler::Source script_source(args[1]->ToString());
413  isolate, &script_source);
414  if (script.IsEmpty()) return;
415  Local<Context> realm = Local<Context>::New(isolate, data->realms_[index]);
416  realm->Enter();
417  Handle<Value> result = script->BindToCurrentContext()->Run();
418  realm->Exit();
419  args.GetReturnValue().Set(result);
420 }
421 
422 
423 // Realm.shared is an accessor for a single shared value across realms.
426  Isolate* isolate = info.GetIsolate();
427  PerIsolateData* data = PerIsolateData::Get(isolate);
428  if (data->realm_shared_.IsEmpty()) return;
429  info.GetReturnValue().Set(data->realm_shared_);
430 }
431 
433  Local<Value> value,
435  Isolate* isolate = info.GetIsolate();
436  PerIsolateData* data = PerIsolateData::Get(isolate);
437  data->realm_shared_.Reset(isolate, value);
438 }
439 
440 
442  Write(args);
443  printf("\n");
444  fflush(stdout);
445 }
446 
447 
449  for (int i = 0; i < args.Length(); i++) {
450  HandleScope handle_scope(args.GetIsolate());
451  if (i != 0) {
452  printf(" ");
453  }
454 
455  // Explicitly catch potential exceptions in toString().
456  v8::TryCatch try_catch;
457  Handle<String> str_obj = args[i]->ToString();
458  if (try_catch.HasCaught()) {
459  try_catch.ReThrow();
460  return;
461  }
462 
463  v8::String::Utf8Value str(str_obj);
464  int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
465  if (n != str.length()) {
466  printf("Error in fwrite\n");
467  Exit(1);
468  }
469  }
470 }
471 
472 
474  String::Utf8Value file(args[0]);
475  if (*file == NULL) {
476  Throw(args.GetIsolate(), "Error loading file");
477  return;
478  }
479  Handle<String> source = ReadFile(args.GetIsolate(), *file);
480  if (source.IsEmpty()) {
481  Throw(args.GetIsolate(), "Error loading file");
482  return;
483  }
484  args.GetReturnValue().Set(source);
485 }
486 
487 
489  static const int kBufferSize = 256;
490  char buffer[kBufferSize];
491  Handle<String> accumulator = String::NewFromUtf8(isolate, "");
492  int length;
493  while (true) {
494  // Continue reading if the line ends with an escape '\\' or the line has
495  // not been fully read into the buffer yet (does not end with '\n').
496  // If fgets gets an error, just give up.
497  char* input = NULL;
498  { // Release lock for blocking input.
499  Unlocker unlock(isolate);
500  input = fgets(buffer, kBufferSize, stdin);
501  }
502  if (input == NULL) return Handle<String>();
503  length = static_cast<int>(strlen(buffer));
504  if (length == 0) {
505  return accumulator;
506  } else if (buffer[length-1] != '\n') {
507  accumulator = String::Concat(
508  accumulator,
509  String::NewFromUtf8(isolate, buffer, String::kNormalString, length));
510  } else if (length > 1 && buffer[length-2] == '\\') {
511  buffer[length-2] = '\n';
512  accumulator = String::Concat(
513  accumulator, String::NewFromUtf8(isolate, buffer,
514  String::kNormalString, length - 1));
515  } else {
516  return String::Concat(
517  accumulator, String::NewFromUtf8(isolate, buffer,
518  String::kNormalString, length - 1));
519  }
520  }
521 }
522 
523 
525  for (int i = 0; i < args.Length(); i++) {
526  HandleScope handle_scope(args.GetIsolate());
527  String::Utf8Value file(args[i]);
528  if (*file == NULL) {
529  Throw(args.GetIsolate(), "Error loading file");
530  return;
531  }
532  Handle<String> source = ReadFile(args.GetIsolate(), *file);
533  if (source.IsEmpty()) {
534  Throw(args.GetIsolate(), "Error loading file");
535  return;
536  }
537  if (!ExecuteString(args.GetIsolate(),
538  source,
539  String::NewFromUtf8(args.GetIsolate(), *file),
540  false,
541  true)) {
542  Throw(args.GetIsolate(), "Error executing file");
543  return;
544  }
545  }
546 }
547 
548 
550  int exit_code = args[0]->Int32Value();
551  OnExit();
552  exit(exit_code);
553 }
554 
555 
557  args.GetReturnValue().Set(
559 }
560 
561 
562 void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
563  HandleScope handle_scope(isolate);
564 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
565  Handle<Context> utility_context;
566  bool enter_context = !isolate->InContext();
567  if (enter_context) {
568  utility_context = Local<Context>::New(isolate, utility_context_);
569  utility_context->Enter();
570  }
571 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
572  v8::String::Utf8Value exception(try_catch->Exception());
573  const char* exception_string = ToCString(exception);
574  Handle<Message> message = try_catch->Message();
575  if (message.IsEmpty()) {
576  // V8 didn't provide any extra information about this error; just
577  // print the exception.
578  printf("%s\n", exception_string);
579  } else {
580  // Print (filename):(line number): (message).
581  v8::String::Utf8Value filename(message->GetScriptResourceName());
582  const char* filename_string = ToCString(filename);
583  int linenum = message->GetLineNumber();
584  printf("%s:%i: %s\n", filename_string, linenum, exception_string);
585  // Print line of source code.
586  v8::String::Utf8Value sourceline(message->GetSourceLine());
587  const char* sourceline_string = ToCString(sourceline);
588  printf("%s\n", sourceline_string);
589  // Print wavy underline (GetUnderline is deprecated).
590  int start = message->GetStartColumn();
591  for (int i = 0; i < start; i++) {
592  printf(" ");
593  }
594  int end = message->GetEndColumn();
595  for (int i = start; i < end; i++) {
596  printf("^");
597  }
598  printf("\n");
599  v8::String::Utf8Value stack_trace(try_catch->StackTrace());
600  if (stack_trace.length() > 0) {
601  const char* stack_trace_string = ToCString(stack_trace);
602  printf("%s\n", stack_trace_string);
603  }
604  }
605  printf("\n");
606 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
607  if (enter_context) utility_context->Exit();
608 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
609 }
610 
611 
612 #ifndef V8_SHARED
614  Handle<String> text,
615  Handle<String> full) {
616  EscapableHandleScope handle_scope(isolate);
617  v8::Local<v8::Context> utility_context =
618  v8::Local<v8::Context>::New(isolate, utility_context_);
619  v8::Context::Scope context_scope(utility_context);
620  Handle<Object> global = utility_context->Global();
621  Local<Value> fun =
622  global->Get(String::NewFromUtf8(isolate, "GetCompletions"));
623  static const int kArgc = 3;
624  v8::Local<v8::Context> evaluation_context =
625  v8::Local<v8::Context>::New(isolate, evaluation_context_);
626  Handle<Value> argv[kArgc] = { evaluation_context->Global(), text, full };
627  Local<Value> val = Local<Function>::Cast(fun)->Call(global, kArgc, argv);
628  return handle_scope.Escape(Local<Array>::Cast(val));
629 }
630 
631 
632 #ifdef ENABLE_DEBUGGER_SUPPORT
633 Local<Object> Shell::DebugMessageDetails(Isolate* isolate,
634  Handle<String> message) {
635  EscapableHandleScope handle_scope(isolate);
636  v8::Local<v8::Context> context =
637  v8::Local<v8::Context>::New(isolate, utility_context_);
638  v8::Context::Scope context_scope(context);
639  Handle<Object> global = context->Global();
640  Handle<Value> fun =
641  global->Get(String::NewFromUtf8(isolate, "DebugMessageDetails"));
642  static const int kArgc = 1;
643  Handle<Value> argv[kArgc] = { message };
644  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
645  return handle_scope.Escape(Local<Object>(Handle<Object>::Cast(val)));
646 }
647 
648 
649 Local<Value> Shell::DebugCommandToJSONRequest(Isolate* isolate,
650  Handle<String> command) {
651  EscapableHandleScope handle_scope(isolate);
652  v8::Local<v8::Context> context =
653  v8::Local<v8::Context>::New(isolate, utility_context_);
654  v8::Context::Scope context_scope(context);
655  Handle<Object> global = context->Global();
656  Handle<Value> fun =
657  global->Get(String::NewFromUtf8(isolate, "DebugCommandToJSONRequest"));
658  static const int kArgc = 1;
659  Handle<Value> argv[kArgc] = { command };
660  Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
661  return handle_scope.Escape(Local<Value>(val));
662 }
663 
664 
665 void Shell::DispatchDebugMessages() {
666  Isolate* isolate = v8::Isolate::GetCurrent();
667  HandleScope handle_scope(isolate);
668  v8::Local<v8::Context> context =
669  v8::Local<v8::Context>::New(isolate, Shell::evaluation_context_);
670  v8::Context::Scope context_scope(context);
672 }
673 #endif // ENABLE_DEBUGGER_SUPPORT
674 #endif // V8_SHARED
675 
676 
677 #ifndef V8_SHARED
678 int32_t* Counter::Bind(const char* name, bool is_histogram) {
679  int i;
680  for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
681  name_[i] = static_cast<char>(name[i]);
682  name_[i] = '\0';
683  is_histogram_ = is_histogram;
684  return ptr();
685 }
686 
687 
689  count_++;
690  sample_total_ += sample;
691 }
692 
693 
695  magic_number_ = 0xDEADFACE;
696  max_counters_ = kMaxCounters;
697  max_name_size_ = Counter::kMaxNameSize;
698  counters_in_use_ = 0;
699 }
700 
701 
703  if (counters_in_use_ == kMaxCounters) return NULL;
704  return &counters_[counters_in_use_++];
705 }
706 
707 
708 void Shell::MapCounters(const char* name) {
709  counters_file_ = i::OS::MemoryMappedFile::create(
710  name, sizeof(CounterCollection), &local_counters_);
711  void* memory = (counters_file_ == NULL) ?
712  NULL : counters_file_->memory();
713  if (memory == NULL) {
714  printf("Could not map counters file %s\n", name);
715  Exit(1);
716  }
717  counters_ = static_cast<CounterCollection*>(memory);
718  V8::SetCounterFunction(LookupCounter);
719  V8::SetCreateHistogramFunction(CreateHistogram);
720  V8::SetAddHistogramSampleFunction(AddHistogramSample);
721 }
722 
723 
724 int CounterMap::Hash(const char* name) {
725  int h = 0;
726  int c;
727  while ((c = *name++) != 0) {
728  h += h << 5;
729  h += c;
730  }
731  return h;
732 }
733 
734 
735 Counter* Shell::GetCounter(const char* name, bool is_histogram) {
736  Counter* counter = counter_map_->Lookup(name);
737 
738  if (counter == NULL) {
739  counter = counters_->GetNextCounter();
740  if (counter != NULL) {
741  counter_map_->Set(name, counter);
742  counter->Bind(name, is_histogram);
743  }
744  } else {
745  ASSERT(counter->is_histogram() == is_histogram);
746  }
747  return counter;
748 }
749 
750 
751 int* Shell::LookupCounter(const char* name) {
752  Counter* counter = GetCounter(name, false);
753 
754  if (counter != NULL) {
755  return counter->ptr();
756  } else {
757  return NULL;
758  }
759 }
760 
761 
762 void* Shell::CreateHistogram(const char* name,
763  int min,
764  int max,
765  size_t buckets) {
766  return GetCounter(name, true);
767 }
768 
769 
770 void Shell::AddHistogramSample(void* histogram, int sample) {
771  Counter* counter = reinterpret_cast<Counter*>(histogram);
772  counter->AddSample(sample);
773 }
774 
775 
776 void Shell::InstallUtilityScript(Isolate* isolate) {
777  Locker lock(isolate);
778  HandleScope scope(isolate);
779  // If we use the utility context, we have to set the security tokens so that
780  // utility, evaluation and debug context can all access each other.
781  v8::Local<v8::Context> utility_context =
782  v8::Local<v8::Context>::New(isolate, utility_context_);
783  v8::Local<v8::Context> evaluation_context =
784  v8::Local<v8::Context>::New(isolate, evaluation_context_);
785  utility_context->SetSecurityToken(Undefined(isolate));
786  evaluation_context->SetSecurityToken(Undefined(isolate));
787  v8::Context::Scope context_scope(utility_context);
788 
789 #ifdef ENABLE_DEBUGGER_SUPPORT
790  if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
791  // Install the debugger object in the utility scope
792  i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
793  debug->Load();
794  i::Handle<i::JSObject> js_debug
795  = i::Handle<i::JSObject>(debug->debug_context()->global_object());
796  utility_context->Global()->Set(String::NewFromUtf8(isolate, "$debug"),
797  Utils::ToLocal(js_debug));
798  debug->debug_context()->set_security_token(
799  reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value());
800 #endif // ENABLE_DEBUGGER_SUPPORT
801 
802  // Run the d8 shell utility script in the utility context
803  int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
804  i::Vector<const char> shell_source =
806  i::Vector<const char> shell_source_name =
808  Handle<String> source =
809  String::NewFromUtf8(isolate, shell_source.start(), String::kNormalString,
810  shell_source.length());
811  Handle<String> name =
812  String::NewFromUtf8(isolate, shell_source_name.start(),
813  String::kNormalString, shell_source_name.length());
814  ScriptOrigin origin(name);
815  Handle<Script> script = Script::Compile(source, &origin);
816  script->Run();
817  // Mark the d8 shell script as native to avoid it showing up as normal source
818  // in the debugger.
819  i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
820  i::Handle<i::Script> script_object = compiled_script->IsJSFunction()
822  i::JSFunction::cast(*compiled_script)->shared()->script()))
823  : i::Handle<i::Script>(i::Script::cast(
824  i::SharedFunctionInfo::cast(*compiled_script)->script()));
825  script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
826 
827 #ifdef ENABLE_DEBUGGER_SUPPORT
828  // Start the in-process debugger if requested.
829  if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
831  }
832 #endif // ENABLE_DEBUGGER_SUPPORT
833 }
834 #endif // V8_SHARED
835 
836 
837 #ifdef COMPRESS_STARTUP_DATA_BZ2
838 class BZip2Decompressor : public v8::StartupDataDecompressor {
839  public:
840  virtual ~BZip2Decompressor() { }
841 
842  protected:
843  virtual int DecompressData(char* raw_data,
844  int* raw_data_size,
845  const char* compressed_data,
846  int compressed_data_size) {
849  unsigned int decompressed_size = *raw_data_size;
850  int result =
851  BZ2_bzBuffToBuffDecompress(raw_data,
852  &decompressed_size,
853  const_cast<char*>(compressed_data),
854  compressed_data_size,
855  0, 1);
856  if (result == BZ_OK) {
857  *raw_data_size = decompressed_size;
858  }
859  return result;
860  }
861 };
862 #endif
863 
864 
865 Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
866  Handle<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
867  global_template->Set(String::NewFromUtf8(isolate, "print"),
868  FunctionTemplate::New(isolate, Print));
869  global_template->Set(String::NewFromUtf8(isolate, "write"),
870  FunctionTemplate::New(isolate, Write));
871  global_template->Set(String::NewFromUtf8(isolate, "read"),
872  FunctionTemplate::New(isolate, Read));
873  global_template->Set(String::NewFromUtf8(isolate, "readbuffer"),
874  FunctionTemplate::New(isolate, ReadBuffer));
875  global_template->Set(String::NewFromUtf8(isolate, "readline"),
876  FunctionTemplate::New(isolate, ReadLine));
877  global_template->Set(String::NewFromUtf8(isolate, "load"),
878  FunctionTemplate::New(isolate, Load));
879  global_template->Set(String::NewFromUtf8(isolate, "quit"),
880  FunctionTemplate::New(isolate, Quit));
881  global_template->Set(String::NewFromUtf8(isolate, "version"),
882  FunctionTemplate::New(isolate, Version));
883 
884  // Bind the Realm object.
885  Handle<ObjectTemplate> realm_template = ObjectTemplate::New(isolate);
886  realm_template->Set(String::NewFromUtf8(isolate, "current"),
887  FunctionTemplate::New(isolate, RealmCurrent));
888  realm_template->Set(String::NewFromUtf8(isolate, "owner"),
889  FunctionTemplate::New(isolate, RealmOwner));
890  realm_template->Set(String::NewFromUtf8(isolate, "global"),
891  FunctionTemplate::New(isolate, RealmGlobal));
892  realm_template->Set(String::NewFromUtf8(isolate, "create"),
893  FunctionTemplate::New(isolate, RealmCreate));
894  realm_template->Set(String::NewFromUtf8(isolate, "dispose"),
895  FunctionTemplate::New(isolate, RealmDispose));
896  realm_template->Set(String::NewFromUtf8(isolate, "switch"),
897  FunctionTemplate::New(isolate, RealmSwitch));
898  realm_template->Set(String::NewFromUtf8(isolate, "eval"),
899  FunctionTemplate::New(isolate, RealmEval));
900  realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"),
901  RealmSharedGet, RealmSharedSet);
902  global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template);
903 
904 #ifndef V8_SHARED
905  Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate);
906  performance_template->Set(String::NewFromUtf8(isolate, "now"),
907  FunctionTemplate::New(isolate, PerformanceNow));
908  global_template->Set(String::NewFromUtf8(isolate, "performance"),
909  performance_template);
910 #endif // V8_SHARED
911 
912 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
913  Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate);
914  AddOSMethods(isolate, os_templ);
915  global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ);
916 #endif // V8_SHARED
917 
918  return global_template;
919 }
920 
921 
922 void Shell::Initialize(Isolate* isolate) {
923 #ifdef COMPRESS_STARTUP_DATA_BZ2
924  BZip2Decompressor startup_data_decompressor;
925  int bz2_result = startup_data_decompressor.Decompress();
926  if (bz2_result != BZ_OK) {
927  fprintf(stderr, "bzip error code: %d\n", bz2_result);
928  Exit(1);
929  }
930 #endif
931 
932 #ifndef V8_SHARED
933  Shell::counter_map_ = new CounterMap();
934  // Set up counters
935  if (i::StrLength(i::FLAG_map_counters) != 0)
936  MapCounters(i::FLAG_map_counters);
937  if (i::FLAG_dump_counters || i::FLAG_track_gc_object_stats) {
938  V8::SetCounterFunction(LookupCounter);
939  V8::SetCreateHistogramFunction(CreateHistogram);
940  V8::SetAddHistogramSampleFunction(AddHistogramSample);
941  }
942 #endif // V8_SHARED
943 }
944 
945 
946 void Shell::InitializeDebugger(Isolate* isolate) {
947  if (options.test_shell) return;
948 #ifndef V8_SHARED
949  Locker lock(isolate);
950  HandleScope scope(isolate);
951  Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
952  utility_context_.Reset(isolate,
953  Context::New(isolate, NULL, global_template));
954 
955 #ifdef ENABLE_DEBUGGER_SUPPORT
956  // Start the debugger agent if requested.
957  if (i::FLAG_debugger_agent) {
958  v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
959  v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
960  }
961 #endif // ENABLE_DEBUGGER_SUPPORT
962 #endif // V8_SHARED
963 }
964 
965 
967 #ifndef V8_SHARED
968  // This needs to be a critical section since this is not thread-safe
969  i::LockGuard<i::Mutex> lock_guard(&context_mutex_);
970 #endif // V8_SHARED
971  // Initialize the global objects
972  Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
973  EscapableHandleScope handle_scope(isolate);
974  Local<Context> context = Context::New(isolate, NULL, global_template);
975  ASSERT(!context.IsEmpty());
976  Context::Scope scope(context);
977 
978 #ifndef V8_SHARED
979  i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
980  i::JSArguments js_args = i::FLAG_js_arguments;
981  i::Handle<i::FixedArray> arguments_array =
982  factory->NewFixedArray(js_args.argc);
983  for (int j = 0; j < js_args.argc; j++) {
985  factory->NewStringFromUtf8(i::CStrVector(js_args[j]));
986  arguments_array->set(j, *arg);
987  }
988  i::Handle<i::JSArray> arguments_jsarray =
989  factory->NewJSArrayWithElements(arguments_array);
990  context->Global()->Set(String::NewFromUtf8(isolate, "arguments"),
991  Utils::ToLocal(arguments_jsarray));
992 #endif // V8_SHARED
993  return handle_scope.Escape(context);
994 }
995 
996 
997 void Shell::Exit(int exit_code) {
998  // Use _exit instead of exit to avoid races between isolate
999  // threads and static destructors.
1000  fflush(stdout);
1001  fflush(stderr);
1002  _exit(exit_code);
1003 }
1004 
1005 
1006 #ifndef V8_SHARED
1009  const char* key;
1010 };
1011 
1012 
1013 inline bool operator<(const CounterAndKey& lhs, const CounterAndKey& rhs) {
1014  return strcmp(lhs.key, rhs.key) < 0;
1015 }
1016 #endif // V8_SHARED
1017 
1018 
1020  LineEditor* line_editor = LineEditor::Get();
1021  if (line_editor) line_editor->Close();
1022 #ifndef V8_SHARED
1023  if (i::FLAG_dump_counters) {
1024  int number_of_counters = 0;
1025  for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
1026  number_of_counters++;
1027  }
1028  CounterAndKey* counters = new CounterAndKey[number_of_counters];
1029  int j = 0;
1030  for (CounterMap::Iterator i(counter_map_); i.More(); i.Next(), j++) {
1031  counters[j].counter = i.CurrentValue();
1032  counters[j].key = i.CurrentKey();
1033  }
1034  std::sort(counters, counters + number_of_counters);
1035  printf("+----------------------------------------------------------------+"
1036  "-------------+\n");
1037  printf("| Name |"
1038  " Value |\n");
1039  printf("+----------------------------------------------------------------+"
1040  "-------------+\n");
1041  for (j = 0; j < number_of_counters; j++) {
1042  Counter* counter = counters[j].counter;
1043  const char* key = counters[j].key;
1044  if (counter->is_histogram()) {
1045  printf("| c:%-60s | %11i |\n", key, counter->count());
1046  printf("| t:%-60s | %11i |\n", key, counter->sample_total());
1047  } else {
1048  printf("| %-62s | %11i |\n", key, counter->count());
1049  }
1050  }
1051  printf("+----------------------------------------------------------------+"
1052  "-------------+\n");
1053  delete [] counters;
1054  }
1055  delete counters_file_;
1056  delete counter_map_;
1057 #endif // V8_SHARED
1058 }
1059 
1060 
1061 
1062 static FILE* FOpen(const char* path, const char* mode) {
1063 #if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
1064  FILE* result;
1065  if (fopen_s(&result, path, mode) == 0) {
1066  return result;
1067  } else {
1068  return NULL;
1069  }
1070 #else
1071  FILE* file = fopen(path, mode);
1072  if (file == NULL) return NULL;
1073  struct stat file_stat;
1074  if (fstat(fileno(file), &file_stat) != 0) return NULL;
1075  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
1076  if (is_regular_file) return file;
1077  fclose(file);
1078  return NULL;
1079 #endif
1080 }
1081 
1082 
1083 static char* ReadChars(Isolate* isolate, const char* name, int* size_out) {
1084  // Release the V8 lock while reading files.
1085  v8::Unlocker unlocker(isolate);
1086  FILE* file = FOpen(name, "rb");
1087  if (file == NULL) return NULL;
1088 
1089  fseek(file, 0, SEEK_END);
1090  int size = ftell(file);
1091  rewind(file);
1092 
1093  char* chars = new char[size + 1];
1094  chars[size] = '\0';
1095  for (int i = 0; i < size;) {
1096  int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
1097  i += read;
1098  }
1099  fclose(file);
1100  *size_out = size;
1101  return chars;
1102 }
1103 
1104 
1106  uint8_t* data;
1108 };
1109 
1110 
1111 static void ReadBufferWeakCallback(
1113  size_t byte_length = data.GetValue()->ByteLength();
1114  data.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(
1115  -static_cast<intptr_t>(byte_length));
1116 
1117  delete[] data.GetParameter()->data;
1118  data.GetParameter()->handle.Reset();
1119  delete data.GetParameter();
1120 }
1121 
1122 
1124  ASSERT(sizeof(char) == sizeof(uint8_t)); // NOLINT
1125  String::Utf8Value filename(args[0]);
1126  int length;
1127  if (*filename == NULL) {
1128  Throw(args.GetIsolate(), "Error loading file");
1129  return;
1130  }
1131 
1132  Isolate* isolate = args.GetIsolate();
1134  data->data = reinterpret_cast<uint8_t*>(
1135  ReadChars(args.GetIsolate(), *filename, &length));
1136  if (data->data == NULL) {
1137  delete data;
1138  Throw(args.GetIsolate(), "Error reading file");
1139  return;
1140  }
1141  Handle<v8::ArrayBuffer> buffer =
1142  ArrayBuffer::New(isolate, data->data, length);
1143  data->handle.Reset(isolate, buffer);
1144  data->handle.SetWeak(data, ReadBufferWeakCallback);
1145  data->handle.MarkIndependent();
1146  isolate->AdjustAmountOfExternalAllocatedMemory(length);
1147 
1148  args.GetReturnValue().Set(buffer);
1149 }
1150 
1151 
1152 #ifndef V8_SHARED
1153 static char* ReadToken(char* data, char token) {
1154  char* next = i::OS::StrChr(data, token);
1155  if (next != NULL) {
1156  *next = '\0';
1157  return (next + 1);
1158  }
1159 
1160  return NULL;
1161 }
1162 
1163 
1164 static char* ReadLine(char* data) {
1165  return ReadToken(data, '\n');
1166 }
1167 
1168 
1169 static char* ReadWord(char* data) {
1170  return ReadToken(data, ' ');
1171 }
1172 #endif // V8_SHARED
1173 
1174 
1175 // Reads a file into a v8 string.
1176 Handle<String> Shell::ReadFile(Isolate* isolate, const char* name) {
1177  int size = 0;
1178  char* chars = ReadChars(isolate, name, &size);
1179  if (chars == NULL) return Handle<String>();
1180  Handle<String> result =
1181  String::NewFromUtf8(isolate, chars, String::kNormalString, size);
1182  delete[] chars;
1183  return result;
1184 }
1185 
1186 
1187 void Shell::RunShell(Isolate* isolate) {
1188  Locker locker(isolate);
1189  HandleScope outer_scope(isolate);
1190  v8::Local<v8::Context> context =
1191  v8::Local<v8::Context>::New(isolate, evaluation_context_);
1192  v8::Context::Scope context_scope(context);
1193  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1194  Handle<String> name = String::NewFromUtf8(isolate, "(d8)");
1195  LineEditor* console = LineEditor::Get();
1196  printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
1197  console->Open(isolate);
1198  while (true) {
1199  HandleScope inner_scope(isolate);
1200  Handle<String> input = console->Prompt(Shell::kPrompt);
1201  if (input.IsEmpty()) break;
1202  ExecuteString(isolate, input, name, true, true);
1203  }
1204  printf("\n");
1205 }
1206 
1207 
1208 #ifndef V8_SHARED
1209 class ShellThread : public i::Thread {
1210  public:
1211  // Takes ownership of the underlying char array of |files|.
1212  ShellThread(Isolate* isolate, char* files)
1213  : Thread("d8:ShellThread"),
1214  isolate_(isolate), files_(files) { }
1215 
1217  delete[] files_;
1218  }
1219 
1220  virtual void Run();
1221  private:
1222  Isolate* isolate_;
1223  char* files_;
1224 };
1225 
1226 
1228  char* ptr = files_;
1229  while ((ptr != NULL) && (*ptr != '\0')) {
1230  // For each newline-separated line.
1231  char* next_line = ReadLine(ptr);
1232 
1233  if (*ptr == '#') {
1234  // Skip comment lines.
1235  ptr = next_line;
1236  continue;
1237  }
1238 
1239  // Prepare the context for this thread.
1240  Locker locker(isolate_);
1241  HandleScope outer_scope(isolate_);
1242  Local<Context> thread_context =
1244  Context::Scope context_scope(thread_context);
1245  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate_));
1246 
1247  while ((ptr != NULL) && (*ptr != '\0')) {
1248  HandleScope inner_scope(isolate_);
1249  char* filename = ptr;
1250  ptr = ReadWord(ptr);
1251 
1252  // Skip empty strings.
1253  if (strlen(filename) == 0) {
1254  continue;
1255  }
1256 
1257  Handle<String> str = Shell::ReadFile(isolate_, filename);
1258  if (str.IsEmpty()) {
1259  printf("File '%s' not found\n", filename);
1260  Shell::Exit(1);
1261  }
1262 
1264  isolate_, str, String::NewFromUtf8(isolate_, filename), false, false);
1265  }
1266 
1267  ptr = next_line;
1268  }
1269 }
1270 #endif // V8_SHARED
1271 
1272 
1274 #ifndef V8_SHARED
1275  delete thread_;
1276  thread_ = NULL;
1277 #endif // V8_SHARED
1278 }
1279 
1280 
1282  bool exception_was_thrown = false;
1283  for (int i = begin_offset_; i < end_offset_; ++i) {
1284  const char* arg = argv_[i];
1285  if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
1286  // Execute argument given to -e option directly.
1287  HandleScope handle_scope(isolate);
1288  Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed");
1289  Handle<String> source = String::NewFromUtf8(isolate, argv_[i + 1]);
1290  if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
1291  exception_was_thrown = true;
1292  break;
1293  }
1294  ++i;
1295  } else if (arg[0] == '-') {
1296  // Ignore other options. They have been parsed already.
1297  } else {
1298  // Use all other arguments as names of files to load and run.
1299  HandleScope handle_scope(isolate);
1300  Handle<String> file_name = String::NewFromUtf8(isolate, arg);
1301  Handle<String> source = ReadFile(isolate, arg);
1302  if (source.IsEmpty()) {
1303  printf("Error reading '%s'\n", arg);
1304  Shell::Exit(1);
1305  }
1306  if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
1307  exception_was_thrown = true;
1308  break;
1309  }
1310  }
1311  }
1312  if (exception_was_thrown != Shell::options.expected_to_throw) {
1313  Shell::Exit(1);
1314  }
1315 }
1316 
1317 
1318 Handle<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) {
1319  int size;
1320  char* chars = ReadChars(isolate, name, &size);
1321  if (chars == NULL) return Handle<String>();
1322  Handle<String> result =
1323  String::NewFromUtf8(isolate, chars, String::kNormalString, size);
1324  delete[] chars;
1325  return result;
1326 }
1327 
1328 
1329 #ifndef V8_SHARED
1330 i::Thread::Options SourceGroup::GetThreadOptions() {
1331  // On some systems (OSX 10.6) the stack size default is 0.5Mb or less
1332  // which is not enough to parse the big literal expressions used in tests.
1333  // The stack size should be at least StackGuard::kLimitSize + some
1334  // OS-specific padding for thread startup code. 2Mbytes seems to be enough.
1335  return i::Thread::Options("IsolateThread", 2 * MB);
1336 }
1337 
1338 
1339 void SourceGroup::ExecuteInThread() {
1340  Isolate* isolate = Isolate::New();
1341  do {
1342  next_semaphore_.Wait();
1343  {
1344  Isolate::Scope iscope(isolate);
1345  Locker lock(isolate);
1346  {
1347  HandleScope scope(isolate);
1348  PerIsolateData data(isolate);
1349  Local<Context> context = Shell::CreateEvaluationContext(isolate);
1350  {
1351  Context::Scope cscope(context);
1352  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1353  Execute(isolate);
1354  }
1355  }
1356  if (Shell::options.send_idle_notification) {
1357  const int kLongIdlePauseInMs = 1000;
1359  V8::IdleNotification(kLongIdlePauseInMs);
1360  }
1361  }
1362  done_semaphore_.Signal();
1363  } while (!Shell::options.last_run);
1364  isolate->Dispose();
1365 }
1366 
1367 
1369  if (thread_ == NULL) {
1370  thread_ = new IsolateThread(this);
1371  thread_->Start();
1372  }
1373  next_semaphore_.Signal();
1374 }
1375 
1376 
1378  if (thread_ == NULL) return;
1379  if (Shell::options.last_run) {
1380  thread_->Join();
1381  } else {
1382  done_semaphore_.Wait();
1383  }
1384 }
1385 #endif // V8_SHARED
1386 
1387 
1388 bool Shell::SetOptions(int argc, char* argv[]) {
1389  for (int i = 0; i < argc; i++) {
1390  if (strcmp(argv[i], "--stress-opt") == 0) {
1391  options.stress_opt = true;
1392  argv[i] = NULL;
1393  } else if (strcmp(argv[i], "--nostress-opt") == 0) {
1394  options.stress_opt = false;
1395  argv[i] = NULL;
1396  } else if (strcmp(argv[i], "--stress-deopt") == 0) {
1397  options.stress_deopt = true;
1398  argv[i] = NULL;
1399  } else if (strcmp(argv[i], "--mock-arraybuffer-allocator") == 0) {
1400  options.mock_arraybuffer_allocator = true;
1401  argv[i] = NULL;
1402  } else if (strcmp(argv[i], "--noalways-opt") == 0) {
1403  // No support for stressing if we can't use --always-opt.
1404  options.stress_opt = false;
1405  options.stress_deopt = false;
1406  } else if (strcmp(argv[i], "--shell") == 0) {
1407  options.interactive_shell = true;
1408  argv[i] = NULL;
1409  } else if (strcmp(argv[i], "--test") == 0) {
1410  options.test_shell = true;
1411  argv[i] = NULL;
1412  } else if (strcmp(argv[i], "--send-idle-notification") == 0) {
1413  options.send_idle_notification = true;
1414  argv[i] = NULL;
1415  } else if (strcmp(argv[i], "-f") == 0) {
1416  // Ignore any -f flags for compatibility with other stand-alone
1417  // JavaScript engines.
1418  continue;
1419  } else if (strcmp(argv[i], "--isolate") == 0) {
1420 #ifdef V8_SHARED
1421  printf("D8 with shared library does not support multi-threading\n");
1422  return false;
1423 #endif // V8_SHARED
1424  options.num_isolates++;
1425  } else if (strcmp(argv[i], "-p") == 0) {
1426 #ifdef V8_SHARED
1427  printf("D8 with shared library does not support multi-threading\n");
1428  return false;
1429 #else
1430  options.num_parallel_files++;
1431 #endif // V8_SHARED
1432  } else if (strcmp(argv[i], "--dump-heap-constants") == 0) {
1433 #ifdef V8_SHARED
1434  printf("D8 with shared library does not support constant dumping\n");
1435  return false;
1436 #else
1437  options.dump_heap_constants = true;
1438  argv[i] = NULL;
1439 #endif
1440  } else if (strcmp(argv[i], "--throws") == 0) {
1441  options.expected_to_throw = true;
1442  argv[i] = NULL;
1443  } else if (strncmp(argv[i], "--icu-data-file=", 16) == 0) {
1444  options.icu_data_file = argv[i] + 16;
1445  argv[i] = NULL;
1446  }
1447 #ifdef V8_SHARED
1448  else if (strcmp(argv[i], "--dump-counters") == 0) {
1449  printf("D8 with shared library does not include counters\n");
1450  return false;
1451  } else if (strcmp(argv[i], "--debugger") == 0) {
1452  printf("Javascript debugger not included\n");
1453  return false;
1454  }
1455 #endif // V8_SHARED
1456  }
1457 
1458 #ifndef V8_SHARED
1459  // Run parallel threads if we are not using --isolate
1460  options.parallel_files = new char*[options.num_parallel_files];
1461  int parallel_files_set = 0;
1462  for (int i = 1; i < argc; i++) {
1463  if (argv[i] == NULL) continue;
1464  if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
1465  if (options.num_isolates > 1) {
1466  printf("-p is not compatible with --isolate\n");
1467  return false;
1468  }
1469  argv[i] = NULL;
1470  i++;
1471  options.parallel_files[parallel_files_set] = argv[i];
1472  parallel_files_set++;
1473  argv[i] = NULL;
1474  }
1475  }
1476  if (parallel_files_set != options.num_parallel_files) {
1477  printf("-p requires a file containing a list of files as parameter\n");
1478  return false;
1479  }
1480 #endif // V8_SHARED
1481 
1482  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
1483 
1484  // Set up isolated source groups.
1485  options.isolate_sources = new SourceGroup[options.num_isolates];
1486  SourceGroup* current = options.isolate_sources;
1487  current->Begin(argv, 1);
1488  for (int i = 1; i < argc; i++) {
1489  const char* str = argv[i];
1490  if (strcmp(str, "--isolate") == 0) {
1491  current->End(i);
1492  current++;
1493  current->Begin(argv, i + 1);
1494  } else if (strncmp(argv[i], "--", 2) == 0) {
1495  printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
1496  }
1497  }
1498  current->End(argc);
1499 
1500  return true;
1501 }
1502 
1503 
1504 int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
1505 #ifndef V8_SHARED
1506  i::List<i::Thread*> threads(1);
1507  if (options.parallel_files != NULL) {
1508  for (int i = 0; i < options.num_parallel_files; i++) {
1509  char* files = NULL;
1510  { Locker lock(isolate);
1511  int size = 0;
1512  files = ReadChars(isolate, options.parallel_files[i], &size);
1513  }
1514  if (files == NULL) {
1515  printf("File list '%s' not found\n", options.parallel_files[i]);
1516  Exit(1);
1517  }
1518  ShellThread* thread = new ShellThread(isolate, files);
1519  thread->Start();
1520  threads.Add(thread);
1521  }
1522  }
1523  for (int i = 1; i < options.num_isolates; ++i) {
1524  options.isolate_sources[i].StartExecuteInThread();
1525  }
1526 #endif // V8_SHARED
1527  { // NOLINT
1528  Locker lock(isolate);
1529  {
1530  HandleScope scope(isolate);
1531  Local<Context> context = CreateEvaluationContext(isolate);
1532  if (options.last_run) {
1533  // Keep using the same context in the interactive shell.
1534  evaluation_context_.Reset(isolate, context);
1535 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1536  // If the interactive debugger is enabled make sure to activate
1537  // it before running the files passed on the command line.
1538  if (i::FLAG_debugger) {
1539  InstallUtilityScript(isolate);
1540  }
1541 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1542  }
1543  {
1544  Context::Scope cscope(context);
1545  PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1546  options.isolate_sources[0].Execute(isolate);
1547  }
1548  }
1549  if (!options.last_run) {
1550  if (options.send_idle_notification) {
1551  const int kLongIdlePauseInMs = 1000;
1553  V8::IdleNotification(kLongIdlePauseInMs);
1554  }
1555  }
1556  }
1557 
1558 #ifndef V8_SHARED
1559  for (int i = 1; i < options.num_isolates; ++i) {
1560  options.isolate_sources[i].WaitForThread();
1561  }
1562 
1563  for (int i = 0; i < threads.length(); i++) {
1564  i::Thread* thread = threads[i];
1565  thread->Join();
1566  delete thread;
1567  }
1568 #endif // V8_SHARED
1569  return 0;
1570 }
1571 
1572 
1573 #ifdef V8_SHARED
1574 static void SetStandaloneFlagsViaCommandLine() {
1575  int fake_argc = 3;
1576  char **fake_argv = new char*[3];
1577  fake_argv[0] = NULL;
1578  fake_argv[1] = strdup("--trace-hydrogen-file=hydrogen.cfg");
1579  fake_argv[2] = strdup("--redirect-code-traces-to=code.asm");
1580  v8::V8::SetFlagsFromCommandLine(&fake_argc, fake_argv, false);
1581  free(fake_argv[1]);
1582  free(fake_argv[2]);
1583  delete[] fake_argv;
1584 }
1585 #endif
1586 
1587 
1588 #ifndef V8_SHARED
1589 static void DumpHeapConstants(i::Isolate* isolate) {
1590  i::Heap* heap = isolate->heap();
1591 
1592  // Dump the INSTANCE_TYPES table to the console.
1593  printf("# List of known V8 instance types.\n");
1594 #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", i::T, #T);
1595  printf("INSTANCE_TYPES = {\n");
1597  printf("}\n");
1598 #undef DUMP_TYPE
1599 
1600  // Dump the KNOWN_MAP table to the console.
1601  printf("\n# List of known V8 maps.\n");
1602 #define ROOT_LIST_CASE(type, name, camel_name) \
1603  if (n == NULL && o == heap->name()) n = #camel_name;
1604 #define STRUCT_LIST_CASE(upper_name, camel_name, name) \
1605  if (n == NULL && o == heap->name##_map()) n = #camel_name "Map";
1606  i::HeapObjectIterator it(heap->map_space());
1607  printf("KNOWN_MAPS = {\n");
1608  for (i::Object* o = it.Next(); o != NULL; o = it.Next()) {
1609  i::Map* m = i::Map::cast(o);
1610  const char* n = NULL;
1611  intptr_t p = reinterpret_cast<intptr_t>(m) & 0xfffff;
1612  int t = m->instance_type();
1615  if (n == NULL) continue;
1616  printf(" 0x%05" V8PRIxPTR ": (%d, \"%s\"),\n", p, t, n);
1617  }
1618  printf("}\n");
1619 #undef STRUCT_LIST_CASE
1620 #undef ROOT_LIST_CASE
1621 
1622  // Dump the KNOWN_OBJECTS table to the console.
1623  printf("\n# List of known V8 objects.\n");
1624 #define ROOT_LIST_CASE(type, name, camel_name) \
1625  if (n == NULL && o == heap->name()) n = #camel_name;
1626  i::OldSpaces spit(heap);
1627  printf("KNOWN_OBJECTS = {\n");
1628  for (i::PagedSpace* s = spit.next(); s != NULL; s = spit.next()) {
1629  i::HeapObjectIterator it(s);
1630  const char* sname = AllocationSpaceName(s->identity());
1631  for (i::Object* o = it.Next(); o != NULL; o = it.Next()) {
1632  const char* n = NULL;
1633  intptr_t p = reinterpret_cast<intptr_t>(o) & 0xfffff;
1635  if (n == NULL) continue;
1636  printf(" (\"%s\", 0x%05" V8PRIxPTR "): \"%s\",\n", sname, p, n);
1637  }
1638  }
1639  printf("}\n");
1640 #undef ROOT_LIST_CASE
1641 }
1642 #endif // V8_SHARED
1643 
1644 
1646  public:
1647  virtual void* Allocate(size_t length) {
1648  void* result = malloc(length);
1649  memset(result, 0, length);
1650  return result;
1651  }
1652  virtual void* AllocateUninitialized(size_t length) {
1653  return malloc(length);
1654  }
1655  virtual void Free(void* data, size_t) { free(data); }
1656  // TODO(dslomov): Remove when v8:2823 is fixed.
1657  virtual void Free(void* data) {
1658 #ifndef V8_SHARED
1659  UNREACHABLE();
1660 #endif
1661  }
1662 };
1663 
1664 
1666  public:
1667  virtual void* Allocate(size_t) V8_OVERRIDE {
1668  return malloc(0);
1669  }
1670  virtual void* AllocateUninitialized(size_t length) V8_OVERRIDE {
1671  return malloc(0);
1672  }
1673  virtual void Free(void*, size_t) V8_OVERRIDE {
1674  }
1675 };
1676 
1677 
1678 int Shell::Main(int argc, char* argv[]) {
1679  if (!SetOptions(argc, argv)) return 1;
1680  v8::V8::InitializeICU(options.icu_data_file);
1681 #ifndef V8_SHARED
1682  i::FLAG_trace_hydrogen_file = "hydrogen.cfg";
1683  i::FLAG_redirect_code_traces_to = "code.asm";
1684 #else
1685  SetStandaloneFlagsViaCommandLine();
1686 #endif
1687  ShellArrayBufferAllocator array_buffer_allocator;
1688  MockArrayBufferAllocator mock_arraybuffer_allocator;
1689  if (options.mock_arraybuffer_allocator) {
1690  v8::V8::SetArrayBufferAllocator(&mock_arraybuffer_allocator);
1691  } else {
1692  v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
1693  }
1694  int result = 0;
1695  Isolate* isolate = Isolate::GetCurrent();
1696 #ifndef V8_SHARED
1697  v8::ResourceConstraints constraints;
1699  i::CPU::NumberOfProcessorsOnline());
1700  v8::SetResourceConstraints(isolate, &constraints);
1701 #endif
1702  DumbLineEditor dumb_line_editor(isolate);
1703  {
1704  Initialize(isolate);
1705 #ifdef ENABLE_VTUNE_JIT_INTERFACE
1706  vTune::InitializeVtuneForV8();
1707 #endif
1708  PerIsolateData data(isolate);
1709  InitializeDebugger(isolate);
1710 
1711 #ifndef V8_SHARED
1712  if (options.dump_heap_constants) {
1713  DumpHeapConstants(reinterpret_cast<i::Isolate*>(isolate));
1714  return 0;
1715  }
1716 #endif
1717 
1718  if (options.stress_opt || options.stress_deopt) {
1719  Testing::SetStressRunType(options.stress_opt
1722  int stress_runs = Testing::GetStressRuns();
1723  for (int i = 0; i < stress_runs && result == 0; i++) {
1724  printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
1726  options.last_run = (i == stress_runs - 1);
1727  result = RunMain(isolate, argc, argv);
1728  }
1729  printf("======== Full Deoptimization =======\n");
1731 #if !defined(V8_SHARED)
1732  } else if (i::FLAG_stress_runs > 0) {
1733  int stress_runs = i::FLAG_stress_runs;
1734  for (int i = 0; i < stress_runs && result == 0; i++) {
1735  printf("============ Run %d/%d ============\n", i + 1, stress_runs);
1736  options.last_run = (i == stress_runs - 1);
1737  result = RunMain(isolate, argc, argv);
1738  }
1739 #endif
1740  } else {
1741  result = RunMain(isolate, argc, argv);
1742  }
1743 
1744 
1745 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1746  // Run remote debugger if requested, but never on --test
1747  if (i::FLAG_remote_debugger && !options.test_shell) {
1748  InstallUtilityScript(isolate);
1749  RunRemoteDebugger(isolate, i::FLAG_debugger_port);
1750  return 0;
1751  }
1752 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1753 
1754  // Run interactive shell if explicitly requested or if no script has been
1755  // executed, but never on --test
1756 
1757  if (( options.interactive_shell || !options.script_executed )
1758  && !options.test_shell ) {
1759 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
1760  if (!i::FLAG_debugger) {
1761  InstallUtilityScript(isolate);
1762  }
1763 #endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
1764  RunShell(isolate);
1765  }
1766  }
1767  V8::Dispose();
1768 
1769  OnExit();
1770 
1771  return result;
1772 }
1773 
1774 } // namespace v8
1775 
1776 
1777 #ifndef GOOGLE3
1778 int main(int argc, char* argv[]) {
1779  return v8::Shell::Main(argc, argv);
1780 }
1781 #endif
void Enter()
Definition: api.cc:650
ShellThread(Isolate *isolate, char *files)
Definition: d8.cc:1212
static Isolate * GetCurrent()
Definition: api.cc:6580
static void Exit(int exit_code)
Definition: d8.cc:997
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
static V8_INLINE Local< T > New(Isolate *isolate, Handle< T > that)
Definition: v8.h:5713
Counter * counter
Definition: d8.cc:1008
uint8_t * data
Definition: d8.cc:1106
static LineEditor * Get()
Definition: d8.h:131
const char * ToCString(const v8::String::Utf8Value &value)
#define V8PRIxPTR
Definition: globals.h:228
uint16_t current_
static int GetStressRuns()
Definition: api.cc:7424
#define INSTANCE_TYPE_LIST(V)
Definition: objects.h:342
~PerIsolateData()
Definition: d8.cc:96
void SetSecurityToken(Handle< Value > token)
Definition: api.cc:5207
Local< Value > Exception() const
Definition: api.cc:1923
static void Read(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:473
V8_INLINE Isolate * GetIsolate() const
Definition: v8.h:6061
static void SetAddHistogramSampleFunction(AddHistogramSampleCallback)
Definition: api.cc:6319
Local< Value > Get(Handle< Value > key)
Definition: api.cc:3139
static Smi * FromInt(int value)
Definition: objects-inl.h:1209
virtual void * AllocateUninitialized(size_t length)
Definition: d8.cc:1652
static bool ExecuteString(Isolate *isolate, Handle< String > source, Handle< Value > name, bool print_result, bool report_exceptions)
Definition: d8.cc:191
static int Main(int argc, char *argv[])
Definition: d8.cc:1678
static int GetIndex(const char *name)
void WaitForThread()
Definition: d8.cc:1377
bool HasCaught() const
Definition: api.cc:1901
static void AddHistogramSample(void *histogram, int sample)
Definition: d8.cc:770
void AddSample(int32_t sample)
Definition: d8.cc:688
V8_INLINE ReturnValue< T > GetReturnValue() const
Definition: v8.h:6067
static int RunMain(Isolate *isolate, int argc, char *argv[])
Definition: d8.cc:1504
virtual void Free(void *data, size_t)
Definition: d8.cc:1655
static Vector< const char > GetRawScriptSource(int index)
static Vector< const char > GetScriptName(int index)
TickSample * sample
Local< Context > GetEnteredContext()
Definition: api.cc:6377
V8_INLINE int Length() const
Definition: v8.h:6079
static Map * cast(Object *obj)
int int32_t
Definition: unicode.cc:47
Handle< JSArray > NewJSArrayWithElements(Handle< FixedArrayBase > elements, ElementsKind elements_kind, int length, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1456
static Handle< Array > GetCompletions(Isolate *isolate, Handle< String > text, Handle< String > full)
Definition: d8.cc:613
int32_t * ptr()
Definition: d8.h:49
static void ReportException(Isolate *isolate, TryCatch *try_catch)
Definition: d8.cc:562
V8_INLINE Local< T > GetValue() const
Definition: v8.h:450
Counter * GetNextCounter()
Definition: d8.cc:702
V8_INLINE Local< T > Escape(Local< T > value)
Definition: v8.h:892
int32_t * Bind(const char *name, bool histogram)
Definition: d8.cc:678
~ShellThread()
Definition: d8.cc:1216
const char * AllocationSpaceName(AllocationSpace space)
#define ASSERT(condition)
Definition: checks.h:329
static Script * cast(Object *obj)
void Quit(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: shell.cc:201
virtual void * AllocateUninitialized(size_t length) V8_OVERRIDE
Definition: d8.cc:1670
static void RealmCurrent(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:324
int main(int argc, char *argv[])
Definition: d8.cc:1778
static const int kMaxNameSize
Definition: d8.h:47
void SetVerbose(bool value)
Definition: api.cc:1976
void Read(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: shell.cc:146
static void RealmSharedGet(Local< String > property, const PropertyCallbackInfo< Value > &info)
Definition: d8.cc:424
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV 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 expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in only print modified registers Don t break for ASM_UNIMPLEMENTED_BREAK macros print stack trace when an illegal exception is thrown randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot testing_bool_flag testing_int_flag string flag tmp file in which to serialize heap Print the time it takes to lazily compile hydrogen code stubs concurrent_recompilation concurrent_sweeping Print usage message
static bool Dispose()
Definition: api.cc:5028
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV 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 expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
static Local< UnboundScript > CompileUnbound(Isolate *isolate, Source *source, CompileOptions options=kNoCompileOptions)
Definition: api.cc:1723
static void Version(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:556
void RunRemoteDebugger(Isolate *isolate, int port)
static const char * GetVersion()
Definition: api.cc:5120
static Local< Context > CreateEvaluationContext(Isolate *isolate)
Definition: d8.cc:966
static ShellOptions options
Definition: d8.h:386
Handle< String > NewStringFromUtf8(Vector< const char > str, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:273
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV 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 expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable memory(in Mbytes)") DEFINE_bool(gc_global
static void Quit(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:549
static void SetArrayBufferAllocator(ArrayBuffer::Allocator *allocator)
Definition: api.cc:5018
const int MB
Definition: d8.cc:174
LineEditor(Type type, const char *name)
Definition: d8.cc:131
RealmScope(PerIsolateData *data)
Definition: d8.cc:268
#define UNREACHABLE()
Definition: checks.h:52
bool is_histogram()
Definition: d8.h:52
friend class RealmScope
Definition: d8.cc:114
T * start() const
Definition: utils.h:426
static Local< ObjectTemplate > New()
Definition: api.cc:1286
V8_INLINE Isolate * GetIsolate() const
Definition: v8.h:449
static Handle< String > ReadFile(Isolate *isolate, const char *name)
Definition: d8.cc:1176
virtual void Free(void *data)
Definition: d8.cc:1657
void HandleDebugEvent(const Debug::EventDetails &event_details)
static void Print(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:441
Handle< Value > ReThrow()
Definition: api.cc:1916
V8_INLINE Isolate * GetIsolate() const
Definition: v8.h:6512
bool V8_EXPORT SetResourceConstraints(Isolate *isolate, ResourceConstraints *constraints)
Definition: api.cc:508
static const char * ToCString(const v8::String::Utf8Value &value)
Definition: d8.cc:185
Vector< const char > ReadFile(const char *filename, bool *exists, bool verbose)
Definition: v8utils.cc:182
#define ROOT_LIST(V)
Definition: heap.h:226
int32_t sample_total()
Definition: d8.h:51
static Isolate * New()
Definition: api.cc:6586
static void RealmGlobal(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:349
static int ContextDisposedNotification()
Definition: api.cc:5108
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >(), int length=0)
Definition: api.cc:942
V8_INLINE void SetData(uint32_t slot, void *data)
Definition: v8.h:6577
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *script_data=NULL)
Definition: api.cc:1832
void Version(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: shell.cc:211
static V8_INLINE Handle< T > Cast(Handle< S > that)
Definition: v8.h:297
Local< Object > Global()
Definition: api.cc:5239
~SourceGroup()
Definition: d8.cc:1273
static Local< ArrayBuffer > New(Isolate *isolate, size_t byte_length)
Definition: api.cc:5994
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:53
bool InContext()
Definition: api.cc:6353
V8_INLINE ReturnValue< T > GetReturnValue() const
Definition: v8.h:6536
int length() const
Definition: utils.h:420
static void SetStressRunType(StressType type)
Definition: api.cc:7419
bool operator<(const CounterAndKey &lhs, const CounterAndKey &rhs)
Definition: d8.cc:1013
static const char * kPrompt
Definition: d8.h:385
void Execute(Isolate *isolate)
Definition: d8.cc:1281
#define ROOT_LIST_CASE(type, name, camel_name)
v8::Handle< v8::ObjectTemplate > CreateGlobalTemplate(v8::Isolate *isolate, v8::FunctionCallback terminate, v8::FunctionCallback doloop)
static bool EnableAgent(const char *name, int port, bool wait_for_connection=false)
Persistent< ArrayBuffer > handle
Definition: d8.cc:1107
static void * CreateHistogram(const char *name, int min, int max, size_t buckets)
Definition: d8.cc:762
const char * name()
Definition: d8.h:130
virtual void * Allocate(size_t length)
Definition: d8.cc:1647
V8_INLINE bool IsUndefined() const
Definition: v8.h:6229
static void RealmCreate(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:359
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition: api.h:308
V8_INLINE Handle< Primitive > Undefined(Isolate *isolate)
Definition: v8.h:6541
static V8_INLINE Local< T > Cast(Local< S > that)
Definition: v8.h:372
Vector< const char > CStrVector(const char *data)
Definition: utils.h:574
V8_INLINE P * GetParameter() const
Definition: v8.h:451
int StrLength(const char *string)
Definition: utils.h:253
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
#define DUMP_TYPE(T)
virtual void * Allocate(size_t) V8_OVERRIDE
Definition: d8.cc:1667
static Local< Context > New(Isolate *isolate, ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:5188
Local< Value > StackTrace() const
Definition: api.cc:1935
void Load(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: shell.cc:171
virtual bool Close()
Definition: d8.h:127
virtual void Free(void *, size_t) V8_OVERRIDE
Definition: d8.cc:1673
Definition: d8.h:268
virtual Handle< String > Prompt(const char *prompt)=0
static void RealmSharedSet(Local< String > property, Local< Value > value, const PropertyCallbackInfo< void > &info)
Definition: d8.cc:432
static void SetDebugMessageDispatchHandler(DebugMessageDispatchHandler handler, bool provide_locker=false)
void Exit()
Definition: api.cc:661
#define V8_OVERRIDE
Definition: v8config.h:402
const char * key
Definition: d8.cc:1009
#define STRUCT_LIST(V)
Definition: objects.h:590
V8_INLINE bool IsEmpty() const
Definition: v8.h:248
int length() const
Definition: v8.h:1955
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
static void RealmEval(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:402
static PerIsolateData * Get(Isolate *isolate)
Definition: d8.cc:100
V8_INLINE void Reset()
Definition: v8.h:5808
static bool SetDebugEventListener2(EventCallback2 that, Handle< Value > data=Handle< Value >())
V8_INLINE void * GetData(uint32_t slot)
Definition: v8.h:6583
static void Load(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:524
virtual bool Open(Isolate *isolate)
Definition: d8.h:126
static bool InitializeICU(const char *icu_data_file=NULL)
Definition: api.cc:5115
static void RealmSwitch(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:392
#define ASSERT_EQ(v1, v2)
Definition: checks.h:330
InstanceType instance_type()
Definition: objects-inl.h:4012
DumbLineEditor(Isolate *isolate)
Definition: d8.cc:139
static void MapCounters(const char *name)
Definition: d8.cc:708
static void PrepareStressRun(int run)
Definition: api.cc:7441
static void SetCreateHistogramFunction(CreateHistogramCallback)
Definition: api.cc:6311
int RunMain(int argc, char *argv[])
void Print(const v8::FunctionCallbackInfo< v8::Value > &args)
MapSpace * map_space()
Definition: heap.h:641
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:39
static Local< String > Concat(Handle< String > left, Handle< String > right)
Definition: api.cc:5456
int32_t count()
Definition: d8.h:50
bool ExecuteString(v8::Isolate *isolate, v8::Handle< v8::String > source, v8::Handle< v8::Value > name, bool print_result, bool report_exceptions)
Definition: shell.cc:300
int64_t AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)
Definition: api.cc:6332
static void RealmDispose(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:377
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV 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_string(expose_natives_as
bool test_shell
Definition: d8.h:256
static void Write(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:448
#define STRUCT_LIST_CASE(upper_name, camel_name, name)
static void SetFlagsFromCommandLine(int *argc, char **argv, bool remove_flags)
Definition: api.cc:411
static void ReadBuffer(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:1123
static int * LookupCounter(const char *name)
Definition: d8.cc:751
void ConfigureDefaults(uint64_t physical_memory, uint32_t number_of_processors)
Definition: api.cc:469
PerIsolateData(Isolate *isolate)
Definition: d8.cc:91
static StartupData::CompressionAlgorithm GetCompressedStartupDataAlgorithm()
Definition: api.cc:306
static Handle< String > ReadFromStdin(Isolate *isolate)
Definition: d8.cc:488
bool script_executed
Definition: d8.h:250
static void DeoptimizeAll()
Definition: api.cc:7477
static void PerformanceNow(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:316
static void ProcessDebugMessages()
void RunShell(v8::Handle< v8::Context > context)
Definition: shell.cc:276
Local< v8::Message > Message() const
Definition: api.cc:1953
Definition: d8.h:45
void StartExecuteInThread()
Definition: d8.cc:1368
static void OnExit()
Definition: d8.cc:1019
virtual Handle< String > Prompt(const char *prompt)
Definition: d8.cc:147
static void RealmOwner(const v8::FunctionCallbackInfo< v8::Value > &args)
Definition: d8.cc:334
static char * StrChr(char *str, int c)
static void SetCounterFunction(CounterLookupCallback)
Definition: api.cc:6305
virtual void Run()
Definition: d8.cc:1227
static Local< String > NewFromUtf8(Isolate *isolate, const char *data, NewStringType type=kNormalString, int length=-1)
Definition: api.cc:5417
static bool IdleNotification(int hint=1000)
Definition: api.cc:5091
static JSFunction * cast(Object *obj)
static uint64_t TotalPhysicalMemory()