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
isolate.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 #include <stdlib.h>
29 
30 #include "v8.h"
31 
32 #include "ast.h"
33 #include "bootstrapper.h"
34 #include "codegen.h"
35 #include "compilation-cache.h"
36 #include "cpu-profiler.h"
37 #include "debug.h"
38 #include "deoptimizer.h"
39 #include "heap-profiler.h"
40 #include "hydrogen.h"
41 #include "isolate-inl.h"
42 #include "lithium-allocator.h"
43 #include "log.h"
44 #include "messages.h"
45 #include "platform.h"
46 #include "regexp-stack.h"
47 #include "runtime-profiler.h"
48 #include "sampler.h"
49 #include "scopeinfo.h"
50 #include "serialize.h"
51 #include "simulator.h"
52 #include "spaces.h"
53 #include "stub-cache.h"
54 #include "sweeper-thread.h"
56 #include "version.h"
57 #include "vm-state-inl.h"
58 
59 
60 namespace v8 {
61 namespace internal {
62 
63 Atomic32 ThreadId::highest_thread_id_ = 0;
64 
65 int ThreadId::AllocateThreadId() {
66  int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
67  return new_id;
68 }
69 
70 
71 int ThreadId::GetCurrentThreadId() {
72  int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
73  if (thread_id == 0) {
74  thread_id = AllocateThreadId();
75  Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
76  }
77  return thread_id;
78 }
79 
80 
81 ThreadLocalTop::ThreadLocalTop() {
82  InitializeInternal();
83 }
84 
85 
86 void ThreadLocalTop::InitializeInternal() {
87  c_entry_fp_ = 0;
88  handler_ = 0;
89 #ifdef USE_SIMULATOR
90  simulator_ = NULL;
91 #endif
92  js_entry_sp_ = NULL;
93  external_callback_scope_ = NULL;
94  current_vm_state_ = EXTERNAL;
95  try_catch_handler_address_ = NULL;
96  context_ = NULL;
97  thread_id_ = ThreadId::Invalid();
98  external_caught_exception_ = false;
99  failed_access_check_callback_ = NULL;
100  save_context_ = NULL;
101  catcher_ = NULL;
102  top_lookup_result_ = NULL;
103 
104  // These members are re-initialized later after deserialization
105  // is complete.
106  pending_exception_ = NULL;
107  has_pending_message_ = false;
108  rethrowing_message_ = false;
109  pending_message_obj_ = NULL;
110  pending_message_script_ = NULL;
111  scheduled_exception_ = NULL;
112 }
113 
114 
115 void ThreadLocalTop::Initialize() {
116  InitializeInternal();
117 #ifdef USE_SIMULATOR
118  simulator_ = Simulator::current(isolate_);
119 #endif
120  thread_id_ = ThreadId::Current();
121 }
122 
123 
124 v8::TryCatch* ThreadLocalTop::TryCatchHandler() {
125  return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address());
126 }
127 
128 
129 Isolate* Isolate::default_isolate_ = NULL;
130 Thread::LocalStorageKey Isolate::isolate_key_;
131 Thread::LocalStorageKey Isolate::thread_id_key_;
132 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
133 #ifdef DEBUG
135 #endif // DEBUG
136 Mutex Isolate::process_wide_mutex_;
137 // TODO(dcarney): Remove with default isolate.
142 };
143 static DefaultIsolateStatus default_isolate_status_
145 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
146 Atomic32 Isolate::isolate_counter_ = 0;
147 
148 Isolate::PerIsolateThreadData*
149  Isolate::FindOrAllocatePerThreadDataForThisThread() {
150  ThreadId thread_id = ThreadId::Current();
151  PerIsolateThreadData* per_thread = NULL;
152  {
153  LockGuard<Mutex> lock_guard(&process_wide_mutex_);
154  per_thread = thread_data_table_->Lookup(this, thread_id);
155  if (per_thread == NULL) {
156  per_thread = new PerIsolateThreadData(this, thread_id);
157  thread_data_table_->Insert(per_thread);
158  }
159  }
160  ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
161  return per_thread;
162 }
163 
164 
166  ThreadId thread_id = ThreadId::Current();
167  return FindPerThreadDataForThread(thread_id);
168 }
169 
170 
172  ThreadId thread_id) {
173  PerIsolateThreadData* per_thread = NULL;
174  {
175  LockGuard<Mutex> lock_guard(&process_wide_mutex_);
176  per_thread = thread_data_table_->Lookup(this, thread_id);
177  }
178  return per_thread;
179 }
180 
181 
183  LockGuard<Mutex> lock_guard(&process_wide_mutex_);
184  CHECK(default_isolate_status_ != kDefaultIsolateInitialized);
185  default_isolate_status_ = kDefaultIsolateCrashIfInitialized;
186 }
187 
188 
190  LockGuard<Mutex> lock_guard(&process_wide_mutex_);
191  CHECK(default_isolate_status_ != kDefaultIsolateCrashIfInitialized);
192  if (default_isolate_ == NULL) {
193  isolate_key_ = Thread::CreateThreadLocalKey();
194  thread_id_key_ = Thread::CreateThreadLocalKey();
195  per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
196 #ifdef DEBUG
198 #endif // DEBUG
199  thread_data_table_ = new Isolate::ThreadDataTable();
200  default_isolate_ = new Isolate();
201  }
202  // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
203  // because a non-null thread data may be already set.
204  if (Thread::GetThreadLocal(isolate_key_) == NULL) {
205  Thread::SetThreadLocal(isolate_key_, default_isolate_);
206  }
207 }
208 
212  }
214 
215 #ifdef ENABLE_DEBUGGER_SUPPORT
216 Debugger* Isolate::GetDefaultIsolateDebugger() {
218  return default_isolate_->debugger();
219 }
220 #endif
221 
222 
225  return default_isolate_->stack_guard();
226 }
227 
228 
231  ASSERT(default_isolate_ != NULL);
232 
234  // If not yet in default isolate - enter it.
235  if (data == NULL || data->isolate() != default_isolate_) {
236  default_isolate_->Enter();
237  }
238 }
239 
240 
243  return reinterpret_cast<v8::Isolate*>(default_isolate_);
244 }
245 
246 
248  return isolate_addresses_[id];
249 }
250 
251 
252 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) {
253  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
254  Iterate(v, thread);
255  return thread_storage + sizeof(ThreadLocalTop);
256 }
257 
258 
260  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
261  v->VisitThread(this, thread);
262 }
263 
264 
265 void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
266  // Visit the roots from the top for a given thread.
267  Object* pending;
268  // The pending exception can sometimes be a failure. We can't show
269  // that to the GC, which only understands objects.
270  if (thread->pending_exception_->ToObject(&pending)) {
271  v->VisitPointer(&pending);
272  thread->pending_exception_ = pending; // In case GC updated it.
273  }
274  v->VisitPointer(&(thread->pending_message_obj_));
275  v->VisitPointer(BitCast<Object**>(&(thread->pending_message_script_)));
276  v->VisitPointer(BitCast<Object**>(&(thread->context_)));
277  Object* scheduled;
278  if (thread->scheduled_exception_->ToObject(&scheduled)) {
279  v->VisitPointer(&scheduled);
280  thread->scheduled_exception_ = scheduled;
281  }
282 
283  for (v8::TryCatch* block = thread->TryCatchHandler();
284  block != NULL;
285  block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
286  v->VisitPointer(BitCast<Object**>(&(block->exception_)));
287  v->VisitPointer(BitCast<Object**>(&(block->message_obj_)));
288  v->VisitPointer(BitCast<Object**>(&(block->message_script_)));
289  }
290 
291  // Iterate over pointers on native execution stack.
292  for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
293  it.frame()->Iterate(v);
294  }
295 
296  // Iterate pointers in live lookup results.
297  thread->top_lookup_result_->Iterate(v);
298 }
299 
300 
301 void Isolate::Iterate(ObjectVisitor* v) {
302  ThreadLocalTop* current_t = thread_local_top();
303  Iterate(v, current_t);
304 }
305 
306 
307 void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) {
308  for (DeferredHandles* deferred = deferred_handles_head_;
309  deferred != NULL;
310  deferred = deferred->next_) {
311  deferred->Iterate(visitor);
312  }
313 }
314 
315 
316 #ifdef DEBUG
317 bool Isolate::IsDeferredHandle(Object** handle) {
318  // Each DeferredHandles instance keeps the handles to one job in the
319  // concurrent recompilation queue, containing a list of blocks. Each block
320  // contains kHandleBlockSize handles except for the first block, which may
321  // not be fully filled.
322  // We iterate through all the blocks to see whether the argument handle
323  // belongs to one of the blocks. If so, it is deferred.
324  for (DeferredHandles* deferred = deferred_handles_head_;
325  deferred != NULL;
326  deferred = deferred->next_) {
327  List<Object**>* blocks = &deferred->blocks_;
328  for (int i = 0; i < blocks->length(); i++) {
329  Object** block_limit = (i == 0) ? deferred->first_block_limit_
330  : blocks->at(i) + kHandleBlockSize;
331  if (blocks->at(i) <= handle && handle < block_limit) return true;
332  }
333  }
334  return false;
335 }
336 #endif // DEBUG
337 
338 
340  // The ARM simulator has a separate JS stack. We therefore register
341  // the C++ try catch handler with the simulator and get back an
342  // address that can be used for comparisons with addresses into the
343  // JS stack. When running without the simulator, the address
344  // returned will be the address of the C++ try catch handler itself.
345  Address address = reinterpret_cast<Address>(
346  SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
347  thread_local_top()->set_try_catch_handler_address(address);
348 }
349 
350 
352  ASSERT(thread_local_top()->TryCatchHandler() == that);
353  thread_local_top()->set_try_catch_handler_address(
354  reinterpret_cast<Address>(that->next_));
355  thread_local_top()->catcher_ = NULL;
357 }
358 
359 
361  if (stack_trace_nesting_level_ == 0) {
362  stack_trace_nesting_level_++;
363  HeapStringAllocator allocator;
365  StringStream accumulator(&allocator);
366  incomplete_message_ = &accumulator;
367  PrintStack(&accumulator);
368  Handle<String> stack_trace = accumulator.ToString(this);
369  incomplete_message_ = NULL;
370  stack_trace_nesting_level_ = 0;
371  return stack_trace;
372  } else if (stack_trace_nesting_level_ == 1) {
373  stack_trace_nesting_level_++;
375  "\n\nAttempt to print stack while printing stack (double fault)\n");
377  "If you are lucky you may find a partial stack dump on stdout.\n\n");
378  incomplete_message_->OutputToStdOut();
379  return factory()->empty_string();
380  } else {
381  OS::Abort();
382  // Unreachable
383  return factory()->empty_string();
384  }
385 }
386 
387 
388 void Isolate::PushStackTraceAndDie(unsigned int magic,
389  Object* object,
390  Map* map,
391  unsigned int magic2) {
392  const int kMaxStackTraceSize = 8192;
394  uint8_t buffer[kMaxStackTraceSize];
395  int length = Min(kMaxStackTraceSize - 1, trace->length());
396  String::WriteToFlat(*trace, buffer, 0, length);
397  buffer[length] = '\0';
398  // TODO(dcarney): convert buffer to utf8?
399  OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n",
400  magic, magic2,
401  static_cast<void*>(object), static_cast<void*>(map),
402  reinterpret_cast<char*>(buffer));
403  OS::Abort();
404 }
405 
406 
407 // Determines whether the given stack frame should be displayed in
408 // a stack trace. The caller is the error constructor that asked
409 // for the stack trace to be collected. The first time a construct
410 // call to this function is encountered it is skipped. The seen_caller
411 // in/out parameter is used to remember if the caller has been seen
412 // yet.
413 static bool IsVisibleInStackTrace(StackFrame* raw_frame,
414  Object* caller,
415  bool* seen_caller) {
416  // Only display JS frames.
417  if (!raw_frame->is_java_script()) return false;
418  JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
419  JSFunction* fun = frame->function();
420  if ((fun == caller) && !(*seen_caller)) {
421  *seen_caller = true;
422  return false;
423  }
424  // Skip all frames until we've seen the caller.
425  if (!(*seen_caller)) return false;
426  // Also, skip non-visible built-in functions and any call with the builtins
427  // object as receiver, so as to not reveal either the builtins object or
428  // an internal function.
429  // The --builtins-in-stack-traces command line flag allows including
430  // internal call sites in the stack trace for debugging purposes.
431  if (!FLAG_builtins_in_stack_traces) {
432  if (frame->receiver()->IsJSBuiltinsObject() ||
433  (fun->IsBuiltin() && !fun->shared()->native())) {
434  return false;
435  }
436  }
437  return true;
438 }
439 
440 
442  Handle<Object> caller,
443  int limit) {
444  limit = Max(limit, 0); // Ensure that limit is not negative.
445  int initial_size = Min(limit, 10);
446  Handle<FixedArray> elements =
447  factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
448 
449  // If the caller parameter is a function we skip frames until we're
450  // under it before starting to collect.
451  bool seen_caller = !caller->IsJSFunction();
452  // First element is reserved to store the number of sloppy frames.
453  int cursor = 1;
454  int frames_seen = 0;
455  int sloppy_frames = 0;
456  bool encountered_strict_function = false;
457  for (StackFrameIterator iter(this);
458  !iter.done() && frames_seen < limit;
459  iter.Advance()) {
460  StackFrame* raw_frame = iter.frame();
461  if (IsVisibleInStackTrace(raw_frame, *caller, &seen_caller)) {
462  frames_seen++;
463  JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
464  // Set initial size to the maximum inlining level + 1 for the outermost
465  // function.
466  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
467  frame->Summarize(&frames);
468  for (int i = frames.length() - 1; i >= 0; i--) {
469  if (cursor + 4 > elements->length()) {
470  int new_capacity = JSObject::NewElementsCapacity(elements->length());
471  Handle<FixedArray> new_elements =
472  factory()->NewFixedArrayWithHoles(new_capacity);
473  for (int i = 0; i < cursor; i++) {
474  new_elements->set(i, elements->get(i));
475  }
476  elements = new_elements;
477  }
478  ASSERT(cursor + 4 <= elements->length());
479 
480  Handle<Object> recv = frames[i].receiver();
481  Handle<JSFunction> fun = frames[i].function();
482  Handle<Code> code = frames[i].code();
483  Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this);
484  // The stack trace API should not expose receivers and function
485  // objects on frames deeper than the top-most one with a strict
486  // mode function. The number of sloppy frames is stored as
487  // first element in the result array.
488  if (!encountered_strict_function) {
489  if (fun->shared()->strict_mode() == STRICT) {
490  encountered_strict_function = true;
491  } else {
492  sloppy_frames++;
493  }
494  }
495  elements->set(cursor++, *recv);
496  elements->set(cursor++, *fun);
497  elements->set(cursor++, *code);
498  elements->set(cursor++, *offset);
499  }
500  }
501  }
502  elements->set(0, Smi::FromInt(sloppy_frames));
503  Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
504  result->set_length(Smi::FromInt(cursor));
505  return result;
506 }
507 
508 
510  if (capture_stack_trace_for_uncaught_exceptions_) {
511  // Capture stack trace for a detailed exception message.
512  Handle<String> key = factory()->hidden_stack_trace_string();
514  stack_trace_for_uncaught_exceptions_frame_limit_,
515  stack_trace_for_uncaught_exceptions_options_);
516  JSObject::SetHiddenProperty(error_object, key, stack_trace);
517  }
518 }
519 
520 
522  int frame_limit, StackTrace::StackTraceOptions options) {
523  // Ensure no negative values.
524  int limit = Max(frame_limit, 0);
525  Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
526 
527  Handle<String> column_key =
529  Handle<String> line_key =
531  Handle<String> script_id_key =
533  Handle<String> script_name_key =
535  Handle<String> script_name_or_source_url_key =
537  STATIC_ASCII_VECTOR("scriptNameOrSourceURL"));
538  Handle<String> function_key =
540  Handle<String> eval_key =
542  Handle<String> constructor_key =
544 
545  StackTraceFrameIterator it(this);
546  int frames_seen = 0;
547  while (!it.done() && (frames_seen < limit)) {
548  JavaScriptFrame* frame = it.frame();
549  // Set initial size to the maximum inlining level + 1 for the outermost
550  // function.
551  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
552  frame->Summarize(&frames);
553  for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
554  // Create a JSObject to hold the information for the StackFrame.
555  Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
556 
557  Handle<JSFunction> fun = frames[i].function();
558  Handle<Script> script(Script::cast(fun->shared()->script()));
559 
560  if (options & StackTrace::kLineNumber) {
561  int script_line_offset = script->line_offset()->value();
562  int position = frames[i].code()->SourcePosition(frames[i].pc());
563  int line_number = GetScriptLineNumber(script, position);
564  // line_number is already shifted by the script_line_offset.
565  int relative_line_number = line_number - script_line_offset;
566  if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
567  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
568  int start = (relative_line_number == 0) ? 0 :
569  Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
570  int column_offset = position - start;
571  if (relative_line_number == 0) {
572  // For the case where the code is on the same line as the script
573  // tag.
574  column_offset += script->column_offset()->value();
575  }
577  this,
579  stack_frame, column_key,
580  Handle<Smi>(Smi::FromInt(column_offset + 1), this), NONE));
581  }
583  this,
585  stack_frame, line_key,
586  Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE));
587  }
588 
589  if (options & StackTrace::kScriptId) {
590  Handle<Smi> script_id(script->id(), this);
593  stack_frame, script_id_key, script_id,
594  NONE));
595  }
596 
597  if (options & StackTrace::kScriptName) {
598  Handle<Object> script_name(script->name(), this);
601  stack_frame, script_name_key, script_name,
602  NONE));
603  }
604 
605  if (options & StackTrace::kScriptNameOrSourceURL) {
606  Handle<Object> result = GetScriptNameOrSourceURL(script);
609  stack_frame, script_name_or_source_url_key,
610  result, NONE));
611  }
612 
613  if (options & StackTrace::kFunctionName) {
614  Handle<Object> fun_name(fun->shared()->name(), this);
615  if (!fun_name->BooleanValue()) {
616  fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
617  }
620  stack_frame, function_key, fun_name, NONE));
621  }
622 
623  if (options & StackTrace::kIsEval) {
624  Handle<Object> is_eval =
625  script->compilation_type() == Script::COMPILATION_TYPE_EVAL ?
626  factory()->true_value() : factory()->false_value();
629  stack_frame, eval_key, is_eval, NONE));
630  }
631 
632  if (options & StackTrace::kIsConstructor) {
633  Handle<Object> is_constructor = (frames[i].is_constructor()) ?
634  factory()->true_value() : factory()->false_value();
637  stack_frame, constructor_key,
638  is_constructor, NONE));
639  }
640 
641  FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
642  frames_seen++;
643  }
644  it.Advance();
645  }
646 
647  stack_trace->set_length(Smi::FromInt(frames_seen));
648  return stack_trace;
649 }
650 
651 
652 void Isolate::PrintStack(FILE* out) {
653  if (stack_trace_nesting_level_ == 0) {
654  stack_trace_nesting_level_++;
656  HeapStringAllocator allocator;
657  StringStream accumulator(&allocator);
658  incomplete_message_ = &accumulator;
659  PrintStack(&accumulator);
660  accumulator.OutputToFile(out);
662  accumulator.Log(this);
663  incomplete_message_ = NULL;
664  stack_trace_nesting_level_ = 0;
665  } else if (stack_trace_nesting_level_ == 1) {
666  stack_trace_nesting_level_++;
668  "\n\nAttempt to print stack while printing stack (double fault)\n");
670  "If you are lucky you may find a partial stack dump on stdout.\n\n");
671  incomplete_message_->OutputToFile(out);
672  }
673 }
674 
675 
676 static void PrintFrames(Isolate* isolate,
677  StringStream* accumulator,
678  StackFrame::PrintMode mode) {
679  StackFrameIterator it(isolate);
680  for (int i = 0; !it.done(); it.Advance()) {
681  it.frame()->Print(accumulator, mode, i++);
682  }
683 }
684 
685 
686 void Isolate::PrintStack(StringStream* accumulator) {
687  if (!IsInitialized()) {
688  accumulator->Add(
689  "\n==== JS stack trace is not available =======================\n\n");
690  accumulator->Add(
691  "\n==== Isolate for the thread is not initialized =============\n\n");
692  return;
693  }
694  // The MentionedObjectCache is not GC-proof at the moment.
696  ASSERT(StringStream::IsMentionedObjectCacheClear(this));
697 
698  // Avoid printing anything if there are no frames.
699  if (c_entry_fp(thread_local_top()) == 0) return;
700 
701  accumulator->Add(
702  "\n==== JS stack trace =========================================\n\n");
703  PrintFrames(this, accumulator, StackFrame::OVERVIEW);
704 
705  accumulator->Add(
706  "\n==== Details ================================================\n\n");
707  PrintFrames(this, accumulator, StackFrame::DETAILS);
708 
709  accumulator->PrintMentionedObjectCache(this);
710  accumulator->Add("=====================\n\n");
711 }
712 
713 
716  thread_local_top()->failed_access_check_callback_ = callback;
717 }
718 
719 
721  if (!thread_local_top()->failed_access_check_callback_) return;
722 
723  ASSERT(receiver->IsAccessCheckNeeded());
724  ASSERT(context());
725 
726  // Get the data object from access check info.
727  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
728  if (!constructor->shared()->IsApiFunction()) return;
729  Object* data_obj =
730  constructor->shared()->get_api_func_data()->access_check_info();
731  if (data_obj == heap_.undefined_value()) return;
732 
733  HandleScope scope(this);
734  Handle<JSObject> receiver_handle(receiver);
735  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
736  { VMState<EXTERNAL> state(this);
737  thread_local_top()->failed_access_check_callback_(
738  v8::Utils::ToLocal(receiver_handle),
739  type,
740  v8::Utils::ToLocal(data));
741  }
742 }
743 
744 
747 };
748 
749 
750 static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
751  JSObject* receiver,
752  v8::AccessType type) {
753  // During bootstrapping, callback functions are not enabled yet.
754  if (isolate->bootstrapper()->IsActive()) return YES;
755 
756  if (receiver->IsJSGlobalProxy()) {
757  Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context();
758  if (!receiver_context->IsContext()) return NO;
759 
760  // Get the native context of current top context.
761  // avoid using Isolate::native_context() because it uses Handle.
762  Context* native_context =
763  isolate->context()->global_object()->native_context();
764  if (receiver_context == native_context) return YES;
765 
766  if (Context::cast(receiver_context)->security_token() ==
767  native_context->security_token())
768  return YES;
769  }
770 
771  return UNKNOWN;
772 }
773 
774 
776  v8::AccessType type) {
777  ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
778 
779  // The callers of this method are not expecting a GC.
781 
782  // Skip checks for hidden properties access. Note, we do not
783  // require existence of a context in this case.
784  if (key == heap_.hidden_string()) return true;
785 
786  // Check for compatibility between the security tokens in the
787  // current lexical context and the accessed object.
788  ASSERT(context());
789 
790  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
791  if (decision != UNKNOWN) return decision == YES;
792 
793  // Get named access check callback
794  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
795  if (!constructor->shared()->IsApiFunction()) return false;
796 
797  Object* data_obj =
798  constructor->shared()->get_api_func_data()->access_check_info();
799  if (data_obj == heap_.undefined_value()) return false;
800 
801  Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
802  v8::NamedSecurityCallback callback =
803  v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
804 
805  if (!callback) return false;
806 
807  HandleScope scope(this);
808  Handle<JSObject> receiver_handle(receiver, this);
809  Handle<Object> key_handle(key, this);
810  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
811  LOG(this, ApiNamedSecurityCheck(key));
812  bool result = false;
813  {
814  // Leaving JavaScript.
815  VMState<EXTERNAL> state(this);
816  result = callback(v8::Utils::ToLocal(receiver_handle),
817  v8::Utils::ToLocal(key_handle),
818  type,
819  v8::Utils::ToLocal(data));
820  }
821  return result;
822 }
823 
824 
826  uint32_t index,
827  v8::AccessType type) {
828  ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
829  // Check for compatibility between the security tokens in the
830  // current lexical context and the accessed object.
831  ASSERT(context());
832 
833  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
834  if (decision != UNKNOWN) return decision == YES;
835 
836  // Get indexed access check callback
837  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
838  if (!constructor->shared()->IsApiFunction()) return false;
839 
840  Object* data_obj =
841  constructor->shared()->get_api_func_data()->access_check_info();
842  if (data_obj == heap_.undefined_value()) return false;
843 
844  Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
845  v8::IndexedSecurityCallback callback =
846  v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
847 
848  if (!callback) return false;
849 
850  HandleScope scope(this);
851  Handle<JSObject> receiver_handle(receiver, this);
852  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
853  LOG(this, ApiIndexedSecurityCheck(index));
854  bool result = false;
855  {
856  // Leaving JavaScript.
857  VMState<EXTERNAL> state(this);
858  result = callback(v8::Utils::ToLocal(receiver_handle),
859  index,
860  type,
861  v8::Utils::ToLocal(data));
862  }
863  return result;
864 }
865 
866 
867 const char* const Isolate::kStackOverflowMessage =
868  "Uncaught RangeError: Maximum call stack size exceeded";
869 
870 
872  HandleScope scope(this);
873  // At this point we cannot create an Error object using its javascript
874  // constructor. Instead, we copy the pre-constructed boilerplate and
875  // attach the stack trace as a hidden property.
876  Handle<String> key = factory()->stack_overflow_string();
877  Handle<JSObject> boilerplate =
879  Handle<JSObject> exception = JSObject::Copy(boilerplate);
880  DoThrow(*exception, NULL);
881 
882  // Get stack trace limit.
883  Handle<Object> error = GetProperty(js_builtins_object(), "$Error");
884  if (!error->IsJSObject()) return Failure::Exception();
885  Handle<Object> stack_trace_limit =
886  GetProperty(Handle<JSObject>::cast(error), "stackTraceLimit");
887  if (!stack_trace_limit->IsNumber()) return Failure::Exception();
888  double dlimit = stack_trace_limit->Number();
889  int limit = std::isnan(dlimit) ? 0 : static_cast<int>(dlimit);
890 
892  exception, factory()->undefined_value(), limit);
893  JSObject::SetHiddenProperty(exception,
894  factory()->hidden_stack_trace_string(),
895  stack_trace);
896  return Failure::Exception();
897 }
898 
899 
901  DoThrow(heap_.termination_exception(), NULL);
902  return Failure::Exception();
903 }
904 
905 
907  if (try_catch_handler()) {
908  try_catch_handler()->has_terminated_ = false;
909  }
910  if (has_pending_exception() &&
911  pending_exception() == heap_.termination_exception()) {
912  thread_local_top()->external_caught_exception_ = false;
914  }
915  if (has_scheduled_exception() &&
916  scheduled_exception() == heap_.termination_exception()) {
917  thread_local_top()->external_caught_exception_ = false;
919  }
920 }
921 
922 
923 Failure* Isolate::Throw(Object* exception, MessageLocation* location) {
924  DoThrow(exception, location);
925  return Failure::Exception();
926 }
927 
928 
929 Failure* Isolate::ReThrow(MaybeObject* exception) {
930  bool can_be_caught_externally = false;
931  bool catchable_by_javascript = is_catchable_by_javascript(exception);
932  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
933 
934  thread_local_top()->catcher_ = can_be_caught_externally ?
936 
937  // Set the exception being re-thrown.
938  set_pending_exception(exception);
939  if (exception->IsFailure()) return exception->ToFailureUnchecked();
940  return Failure::Exception();
941 }
942 
943 
945  if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
946  return Throw(heap_.illegal_access_string());
947 }
948 
949 
951  return Throw(*factory()->NewRangeError(
952  "invalid_string_length", HandleVector<Object>(NULL, 0)));
953 }
954 
955 
956 void Isolate::ScheduleThrow(Object* exception) {
957  // When scheduling a throw we first throw the exception to get the
958  // error reporting if it is uncaught before rescheduling it.
959  Throw(exception);
960  PropagatePendingExceptionToExternalTryCatch();
961  if (has_pending_exception()) {
962  thread_local_top()->scheduled_exception_ = pending_exception();
963  thread_local_top()->external_caught_exception_ = false;
965  }
966 }
967 
968 
970  ASSERT(handler == try_catch_handler());
971  ASSERT(handler->HasCaught());
972  ASSERT(handler->rethrow_);
973  ASSERT(handler->capture_message_);
974  Object* message = reinterpret_cast<Object*>(handler->message_obj_);
975  Object* script = reinterpret_cast<Object*>(handler->message_script_);
976  ASSERT(message->IsJSMessageObject() || message->IsTheHole());
977  ASSERT(script->IsScript() || script->IsTheHole());
978  thread_local_top()->pending_message_obj_ = message;
979  thread_local_top()->pending_message_script_ = script;
980  thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_;
981  thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_;
982 }
983 
984 
986  MaybeObject* thrown = scheduled_exception();
988  // Re-throw the exception to avoid getting repeated error reporting.
989  return ReThrow(thrown);
990 }
991 
992 
994  StackTraceFrameIterator it(this);
995  while (!it.done()) {
996  HandleScope scope(this);
997  // Find code position if recorded in relocation info.
998  JavaScriptFrame* frame = it.frame();
999  int pos = frame->LookupCode()->SourcePosition(frame->pc());
1000  Handle<Object> pos_obj(Smi::FromInt(pos), this);
1001  // Fetch function and receiver.
1002  Handle<JSFunction> fun(frame->function());
1003  Handle<Object> recv(frame->receiver(), this);
1004  // Advance to the next JavaScript frame and determine if the
1005  // current frame is the top-level frame.
1006  it.Advance();
1007  Handle<Object> is_top_level = it.done()
1008  ? factory()->true_value()
1009  : factory()->false_value();
1010  // Generate and print stack trace line.
1011  Handle<String> line =
1012  Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
1013  if (line->length() > 0) {
1014  line->PrintOn(out);
1015  PrintF(out, "\n");
1016  }
1017  }
1018 }
1019 
1020 
1022  *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
1023  StackTraceFrameIterator it(this);
1024  if (!it.done()) {
1025  JavaScriptFrame* frame = it.frame();
1026  JSFunction* fun = frame->function();
1027  Object* script = fun->shared()->script();
1028  if (script->IsScript() &&
1029  !(Script::cast(script)->source()->IsUndefined())) {
1030  int pos = frame->LookupCode()->SourcePosition(frame->pc());
1031  // Compute the location from the function and the reloc info.
1032  Handle<Script> casted_script(Script::cast(script));
1033  *target = MessageLocation(casted_script, pos, pos + 1);
1034  }
1035  }
1036 }
1037 
1038 
1039 bool Isolate::ShouldReportException(bool* can_be_caught_externally,
1040  bool catchable_by_javascript) {
1041  // Find the top-most try-catch handler.
1042  StackHandler* handler =
1043  StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1044  while (handler != NULL && !handler->is_catch()) {
1045  handler = handler->next();
1046  }
1047 
1048  // Get the address of the external handler so we can compare the address to
1049  // determine which one is closer to the top of the stack.
1050  Address external_handler_address =
1051  thread_local_top()->try_catch_handler_address();
1052 
1053  // The exception has been externally caught if and only if there is
1054  // an external handler which is on top of the top-most try-catch
1055  // handler.
1056  *can_be_caught_externally = external_handler_address != NULL &&
1057  (handler == NULL || handler->address() > external_handler_address ||
1058  !catchable_by_javascript);
1059 
1060  if (*can_be_caught_externally) {
1061  // Only report the exception if the external handler is verbose.
1062  return try_catch_handler()->is_verbose_;
1063  } else {
1064  // Report the exception if it isn't caught by JavaScript code.
1065  return handler == NULL;
1066  }
1067 }
1068 
1069 
1070 bool Isolate::IsErrorObject(Handle<Object> obj) {
1071  if (!obj->IsJSObject()) return false;
1072 
1073  String* error_key =
1075  Object* error_constructor =
1076  js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
1077 
1078  for (Object* prototype = *obj; !prototype->IsNull();
1079  prototype = prototype->GetPrototype(this)) {
1080  if (!prototype->IsJSObject()) return false;
1081  if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
1082  return true;
1083  }
1084  }
1085  return false;
1086 }
1087 
1088 static int fatal_exception_depth = 0;
1089 
1090 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
1092 
1093  HandleScope scope(this);
1094  Handle<Object> exception_handle(exception, this);
1095 
1096  // Determine reporting and whether the exception is caught externally.
1097  bool catchable_by_javascript = is_catchable_by_javascript(exception);
1098  bool can_be_caught_externally = false;
1099  bool should_report_exception =
1100  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
1101  bool report_exception = catchable_by_javascript && should_report_exception;
1102  bool try_catch_needs_message =
1103  can_be_caught_externally && try_catch_handler()->capture_message_ &&
1104  !thread_local_top()->rethrowing_message_;
1105  bool bootstrapping = bootstrapper()->IsActive();
1106 
1107  thread_local_top()->rethrowing_message_ = false;
1108 
1109 #ifdef ENABLE_DEBUGGER_SUPPORT
1110  // Notify debugger of exception.
1111  if (catchable_by_javascript) {
1112  debugger_->OnException(exception_handle, report_exception);
1113  }
1114 #endif
1115 
1116  // Generate the message if required.
1117  if (report_exception || try_catch_needs_message) {
1118  MessageLocation potential_computed_location;
1119  if (location == NULL) {
1120  // If no location was specified we use a computed one instead.
1121  ComputeLocation(&potential_computed_location);
1122  location = &potential_computed_location;
1123  }
1124  // It's not safe to try to make message objects or collect stack traces
1125  // while the bootstrapper is active since the infrastructure may not have
1126  // been properly initialized.
1127  if (!bootstrapping) {
1128  Handle<JSArray> stack_trace_object;
1129  if (capture_stack_trace_for_uncaught_exceptions_) {
1130  if (IsErrorObject(exception_handle)) {
1131  // We fetch the stack trace that corresponds to this error object.
1132  String* key = heap()->hidden_stack_trace_string();
1133  Object* stack_property =
1134  JSObject::cast(*exception_handle)->GetHiddenProperty(key);
1135  // Property lookup may have failed. In this case it's probably not
1136  // a valid Error object.
1137  if (stack_property->IsJSArray()) {
1138  stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
1139  }
1140  }
1141  if (stack_trace_object.is_null()) {
1142  // Not an error object, we capture at throw site.
1143  stack_trace_object = CaptureCurrentStackTrace(
1144  stack_trace_for_uncaught_exceptions_frame_limit_,
1145  stack_trace_for_uncaught_exceptions_options_);
1146  }
1147  }
1148 
1149  Handle<Object> exception_arg = exception_handle;
1150  // If the exception argument is a custom object, turn it into a string
1151  // before throwing as uncaught exception. Note that the pending
1152  // exception object to be set later must not be turned into a string.
1153  if (exception_arg->IsJSObject() && !IsErrorObject(exception_arg)) {
1154  bool failed = false;
1155  exception_arg =
1156  Execution::ToDetailString(this, exception_arg, &failed);
1157  if (failed) {
1158  exception_arg = factory()->InternalizeOneByteString(
1159  STATIC_ASCII_VECTOR("exception"));
1160  }
1161  }
1163  this,
1164  "uncaught_exception",
1165  location,
1166  HandleVector<Object>(&exception_arg, 1),
1167  stack_trace_object);
1168  thread_local_top()->pending_message_obj_ = *message_obj;
1169  if (location != NULL) {
1170  thread_local_top()->pending_message_script_ = *location->script();
1171  thread_local_top()->pending_message_start_pos_ = location->start_pos();
1172  thread_local_top()->pending_message_end_pos_ = location->end_pos();
1173  }
1174 
1175  // If the abort-on-uncaught-exception flag is specified, abort on any
1176  // exception not caught by JavaScript, even when an external handler is
1177  // present. This flag is intended for use by JavaScript developers, so
1178  // print a user-friendly stack trace (not an internal one).
1179  if (fatal_exception_depth == 0 &&
1180  FLAG_abort_on_uncaught_exception &&
1181  (report_exception || can_be_caught_externally)) {
1182  fatal_exception_depth++;
1183  PrintF(stderr,
1184  "%s\n\nFROM\n",
1185  MessageHandler::GetLocalizedMessage(this, message_obj).get());
1186  PrintCurrentStackTrace(stderr);
1187  OS::Abort();
1188  }
1189  } else if (location != NULL && !location->script().is_null()) {
1190  // We are bootstrapping and caught an error where the location is set
1191  // and we have a script for the location.
1192  // In this case we could have an extension (or an internal error
1193  // somewhere) and we print out the line number at which the error occured
1194  // to the console for easier debugging.
1195  int line_number = GetScriptLineNumberSafe(location->script(),
1196  location->start_pos());
1197  if (exception->IsString() && location->script()->name()->IsString()) {
1199  "Extension or internal compilation error: %s in %s at line %d.\n",
1200  String::cast(exception)->ToCString().get(),
1201  String::cast(location->script()->name())->ToCString().get(),
1202  line_number + 1);
1203  } else if (location->script()->name()->IsString()) {
1205  "Extension or internal compilation error in %s at line %d.\n",
1206  String::cast(location->script()->name())->ToCString().get(),
1207  line_number + 1);
1208  } else {
1209  OS::PrintError("Extension or internal compilation error.\n");
1210  }
1211  }
1212  }
1213 
1214  // Save the message for reporting if the the exception remains uncaught.
1215  thread_local_top()->has_pending_message_ = report_exception;
1216 
1217  // Do not forget to clean catcher_ if currently thrown exception cannot
1218  // be caught. If necessary, ReThrow will update the catcher.
1219  thread_local_top()->catcher_ = can_be_caught_externally ?
1220  try_catch_handler() : NULL;
1221 
1222  set_pending_exception(*exception_handle);
1223 }
1224 
1225 
1228 
1229  if ((thread_local_top()->catcher_ == NULL) ||
1230  (try_catch_handler() != thread_local_top()->catcher_)) {
1231  // When throwing the exception, we found no v8::TryCatch
1232  // which should care about this exception.
1233  return false;
1234  }
1235 
1237  return true;
1238  }
1239 
1240  // Get the address of the external handler so we can compare the address to
1241  // determine which one is closer to the top of the stack.
1242  Address external_handler_address =
1243  thread_local_top()->try_catch_handler_address();
1244  ASSERT(external_handler_address != NULL);
1245 
1246  // The exception has been externally caught if and only if there is
1247  // an external handler which is on top of the top-most try-finally
1248  // handler.
1249  // There should be no try-catch blocks as they would prohibit us from
1250  // finding external catcher in the first place (see catcher_ check above).
1251  //
1252  // Note, that finally clause would rethrow an exception unless it's
1253  // aborted by jumps in control flow like return, break, etc. and we'll
1254  // have another chances to set proper v8::TryCatch.
1255  StackHandler* handler =
1256  StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1257  while (handler != NULL && handler->address() < external_handler_address) {
1258  ASSERT(!handler->is_catch());
1259  if (handler->is_finally()) return false;
1260 
1261  handler = handler->next();
1262  }
1263 
1264  return true;
1265 }
1266 
1267 
1270  PropagatePendingExceptionToExternalTryCatch();
1271 
1272  HandleScope scope(this);
1273  if (thread_local_top_.pending_exception_ ==
1274  heap()->termination_exception()) {
1275  // Do nothing: if needed, the exception has been already propagated to
1276  // v8::TryCatch.
1277  } else {
1278  if (thread_local_top_.has_pending_message_) {
1279  thread_local_top_.has_pending_message_ = false;
1280  if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
1281  HandleScope scope(this);
1282  Handle<Object> message_obj(thread_local_top_.pending_message_obj_,
1283  this);
1284  if (!thread_local_top_.pending_message_script_->IsTheHole()) {
1285  Handle<Script> script(
1286  Script::cast(thread_local_top_.pending_message_script_));
1287  int start_pos = thread_local_top_.pending_message_start_pos_;
1288  int end_pos = thread_local_top_.pending_message_end_pos_;
1289  MessageLocation location(script, start_pos, end_pos);
1290  MessageHandler::ReportMessage(this, &location, message_obj);
1291  } else {
1292  MessageHandler::ReportMessage(this, NULL, message_obj);
1293  }
1294  }
1295  }
1296  }
1298 }
1299 
1300 
1303 
1304  if (thread_local_top_.pending_exception_ != heap()->termination_exception() &&
1305  thread_local_top_.has_pending_message_ &&
1306  !thread_local_top_.pending_message_obj_->IsTheHole() &&
1307  !thread_local_top_.pending_message_obj_->IsTheHole()) {
1308  Handle<Script> script(
1309  Script::cast(thread_local_top_.pending_message_script_));
1310  int start_pos = thread_local_top_.pending_message_start_pos_;
1311  int end_pos = thread_local_top_.pending_message_end_pos_;
1312  return MessageLocation(script, start_pos, end_pos);
1313  }
1314 
1315  return MessageLocation();
1316 }
1317 
1318 
1319 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
1321  PropagatePendingExceptionToExternalTryCatch();
1322 
1323  bool is_termination_exception =
1324  pending_exception() == heap_.termination_exception();
1325 
1326  // Do not reschedule the exception if this is the bottom call.
1327  bool clear_exception = is_bottom_call;
1328 
1329  if (is_termination_exception) {
1330  if (is_bottom_call) {
1331  thread_local_top()->external_caught_exception_ = false;
1333  return false;
1334  }
1335  } else if (thread_local_top()->external_caught_exception_) {
1336  // If the exception is externally caught, clear it if there are no
1337  // JavaScript frames on the way to the C++ frame that has the
1338  // external handler.
1340  Address external_handler_address =
1341  thread_local_top()->try_catch_handler_address();
1342  JavaScriptFrameIterator it(this);
1343  if (it.done() || (it.frame()->sp() > external_handler_address)) {
1344  clear_exception = true;
1345  }
1346  }
1347 
1348  // Clear the exception if needed.
1349  if (clear_exception) {
1350  thread_local_top()->external_caught_exception_ = false;
1352  return false;
1353  }
1354 
1355  // Reschedule the exception.
1356  thread_local_top()->scheduled_exception_ = pending_exception();
1358  return true;
1359 }
1360 
1361 
1363  bool capture,
1364  int frame_limit,
1366  capture_stack_trace_for_uncaught_exceptions_ = capture;
1367  stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
1368  stack_trace_for_uncaught_exceptions_options_ = options;
1369 }
1370 
1371 
1373  return Handle<Context>(context()->global_object()->native_context());
1374 }
1375 
1376 
1378  return Handle<Context>(context()->global_object()->global_context());
1379 }
1380 
1381 
1383  JavaScriptFrameIterator it(this);
1384 #ifdef ENABLE_DEBUGGER_SUPPORT
1385  if (debug_->InDebugger()) {
1386  while (!it.done()) {
1387  JavaScriptFrame* frame = it.frame();
1388  Context* context = Context::cast(frame->context());
1389  if (context->native_context() == *debug_->debug_context()) {
1390  it.Advance();
1391  } else {
1392  break;
1393  }
1394  }
1395  }
1396 #endif // ENABLE_DEBUGGER_SUPPORT
1397  if (it.done()) return Handle<Context>::null();
1398  JavaScriptFrame* frame = it.frame();
1399  Context* context = Context::cast(frame->context());
1400  return Handle<Context>(context->native_context());
1401 }
1402 
1403 
1404 char* Isolate::ArchiveThread(char* to) {
1405  OS::MemCopy(to, reinterpret_cast<char*>(thread_local_top()),
1406  sizeof(ThreadLocalTop));
1407  InitializeThreadLocal();
1411  return to + sizeof(ThreadLocalTop);
1412 }
1413 
1414 
1415 char* Isolate::RestoreThread(char* from) {
1416  OS::MemCopy(reinterpret_cast<char*>(thread_local_top()), from,
1417  sizeof(ThreadLocalTop));
1418  // This might be just paranoia, but it seems to be needed in case a
1419  // thread_local_top_ is restored on a separate OS thread.
1420 #ifdef USE_SIMULATOR
1421  thread_local_top()->simulator_ = Simulator::current(this);
1422 #endif
1423  ASSERT(context() == NULL || context()->IsContext());
1424  return from + sizeof(ThreadLocalTop);
1425 }
1426 
1427 
1428 Isolate::ThreadDataTable::ThreadDataTable()
1429  : list_(NULL) {
1430 }
1431 
1432 
1433 Isolate::ThreadDataTable::~ThreadDataTable() {
1434  // TODO(svenpanne) The assertion below would fire if an embedder does not
1435  // cleanly dispose all Isolates before disposing v8, so we are conservative
1436  // and leave it out for now.
1437  // ASSERT_EQ(NULL, list_);
1438 }
1439 
1440 
1442 #if defined(USE_SIMULATOR)
1443  delete simulator_;
1444 #endif
1445 }
1446 
1447 
1449  Isolate::ThreadDataTable::Lookup(Isolate* isolate,
1450  ThreadId thread_id) {
1451  for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
1452  if (data->Matches(isolate, thread_id)) return data;
1453  }
1454  return NULL;
1455 }
1456 
1457 
1458 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
1459  if (list_ != NULL) list_->prev_ = data;
1460  data->next_ = list_;
1461  list_ = data;
1462 }
1463 
1464 
1465 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
1466  if (list_ == data) list_ = data->next_;
1467  if (data->next_ != NULL) data->next_->prev_ = data->prev_;
1468  if (data->prev_ != NULL) data->prev_->next_ = data->next_;
1469  delete data;
1470 }
1471 
1472 
1473 void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
1474  PerIsolateThreadData* data = list_;
1475  while (data != NULL) {
1476  PerIsolateThreadData* next = data->next_;
1477  if (data->isolate() == isolate) Remove(data);
1478  data = next;
1479  }
1480 }
1481 
1482 
1483 #ifdef DEBUG
1484 #define TRACE_ISOLATE(tag) \
1485  do { \
1486  if (FLAG_trace_isolates) { \
1487  PrintF("Isolate %p (id %d)" #tag "\n", \
1488  reinterpret_cast<void*>(this), id()); \
1489  } \
1490  } while (false)
1491 #else
1492 #define TRACE_ISOLATE(tag)
1493 #endif
1494 
1495 
1496 Isolate::Isolate()
1497  : embedder_data_(),
1498  state_(UNINITIALIZED),
1499  entry_stack_(NULL),
1500  stack_trace_nesting_level_(0),
1501  incomplete_message_(NULL),
1502  bootstrapper_(NULL),
1503  runtime_profiler_(NULL),
1504  compilation_cache_(NULL),
1505  counters_(NULL),
1506  code_range_(NULL),
1507  debugger_initialized_(false),
1508  logger_(NULL),
1509  stats_table_(NULL),
1510  stub_cache_(NULL),
1511  deoptimizer_data_(NULL),
1512  materialized_object_store_(NULL),
1513  capture_stack_trace_for_uncaught_exceptions_(false),
1514  stack_trace_for_uncaught_exceptions_frame_limit_(0),
1515  stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
1516  memory_allocator_(NULL),
1517  keyed_lookup_cache_(NULL),
1518  context_slot_cache_(NULL),
1519  descriptor_lookup_cache_(NULL),
1520  handle_scope_implementer_(NULL),
1521  unicode_cache_(NULL),
1522  runtime_zone_(this),
1523  inner_pointer_to_code_cache_(NULL),
1524  write_iterator_(NULL),
1525  global_handles_(NULL),
1526  eternal_handles_(NULL),
1527  thread_manager_(NULL),
1528  has_installed_extensions_(false),
1529  string_tracker_(NULL),
1530  regexp_stack_(NULL),
1531  date_cache_(NULL),
1532  code_stub_interface_descriptors_(NULL),
1533  call_descriptors_(NULL),
1534  // TODO(bmeurer) Initialized lazily because it depends on flags; can
1535  // be fixed once the default isolate cleanup is done.
1536  random_number_generator_(NULL),
1537  has_fatal_error_(false),
1538  use_crankshaft_(true),
1539  initialized_from_snapshot_(false),
1540  cpu_profiler_(NULL),
1541  heap_profiler_(NULL),
1542  function_entry_hook_(NULL),
1543  deferred_handles_head_(NULL),
1544  optimizing_compiler_thread_(NULL),
1545  sweeper_thread_(NULL),
1546  num_sweeper_threads_(0),
1547  stress_deopt_count_(0),
1548  next_optimization_id_(0) {
1549  id_ = NoBarrier_AtomicIncrement(&isolate_counter_, 1);
1550  TRACE_ISOLATE(constructor);
1551 
1552  memset(isolate_addresses_, 0,
1553  sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
1554 
1555  heap_.isolate_ = this;
1556  stack_guard_.isolate_ = this;
1557 
1558  // ThreadManager is initialized early to support locking an isolate
1559  // before it is entered.
1560  thread_manager_ = new ThreadManager();
1561  thread_manager_->isolate_ = this;
1562 
1563 #ifdef DEBUG
1564  // heap_histograms_ initializes itself.
1565  memset(&js_spill_information_, 0, sizeof(js_spill_information_));
1566 #endif
1567 
1568 #ifdef ENABLE_DEBUGGER_SUPPORT
1569  debug_ = NULL;
1570  debugger_ = NULL;
1571 #endif
1572 
1573  handle_scope_data_.Initialize();
1574 
1575 #define ISOLATE_INIT_EXECUTE(type, name, initial_value) \
1576  name##_ = (initial_value);
1578 #undef ISOLATE_INIT_EXECUTE
1579 
1580 #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length) \
1581  memset(name##_, 0, sizeof(type) * length);
1583 #undef ISOLATE_INIT_ARRAY_EXECUTE
1584 }
1585 
1586 
1587 void Isolate::TearDown() {
1588  TRACE_ISOLATE(tear_down);
1589 
1590  // Temporarily set this isolate as current so that various parts of
1591  // the isolate can access it in their destructors without having a
1592  // direct pointer. We don't use Enter/Exit here to avoid
1593  // initializing the thread data.
1594  PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
1595  Isolate* saved_isolate = UncheckedCurrent();
1596  SetIsolateThreadLocals(this, NULL);
1597 
1598  Deinit();
1599 
1600  { LockGuard<Mutex> lock_guard(&process_wide_mutex_);
1601  thread_data_table_->RemoveAllThreads(this);
1602  }
1603 
1604  if (serialize_partial_snapshot_cache_ != NULL) {
1605  delete[] serialize_partial_snapshot_cache_;
1606  serialize_partial_snapshot_cache_ = NULL;
1607  }
1608 
1609  if (!IsDefaultIsolate()) {
1610  delete this;
1611  }
1612 
1613  // Restore the previous current isolate.
1614  SetIsolateThreadLocals(saved_isolate, saved_data);
1615 }
1616 
1617 
1618 void Isolate::GlobalTearDown() {
1619  delete thread_data_table_;
1620 }
1621 
1622 
1623 void Isolate::Deinit() {
1624  if (state_ == INITIALIZED) {
1625  TRACE_ISOLATE(deinit);
1626 
1627 #ifdef ENABLE_DEBUGGER_SUPPORT
1628  debugger()->UnloadDebugger();
1629 #endif
1630 
1631  if (concurrent_recompilation_enabled()) {
1632  optimizing_compiler_thread_->Stop();
1633  delete optimizing_compiler_thread_;
1634  optimizing_compiler_thread_ = NULL;
1635  }
1636 
1637  for (int i = 0; i < num_sweeper_threads_; i++) {
1638  sweeper_thread_[i]->Stop();
1639  delete sweeper_thread_[i];
1640  sweeper_thread_[i] = NULL;
1641  }
1642  delete[] sweeper_thread_;
1643  sweeper_thread_ = NULL;
1644 
1645  if (FLAG_job_based_sweeping &&
1646  heap_.mark_compact_collector()->IsConcurrentSweepingInProgress()) {
1647  heap_.mark_compact_collector()->WaitUntilSweepingCompleted();
1648  }
1649 
1650  if (FLAG_hydrogen_stats) GetHStatistics()->Print();
1651 
1652  if (FLAG_print_deopt_stress) {
1653  PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
1654  }
1655 
1656  // We must stop the logger before we tear down other components.
1657  Sampler* sampler = logger_->sampler();
1658  if (sampler && sampler->IsActive()) sampler->Stop();
1659 
1660  delete deoptimizer_data_;
1661  deoptimizer_data_ = NULL;
1662  builtins_.TearDown();
1663  bootstrapper_->TearDown();
1664 
1665  if (runtime_profiler_ != NULL) {
1666  delete runtime_profiler_;
1667  runtime_profiler_ = NULL;
1668  }
1669  heap_.TearDown();
1670  logger_->TearDown();
1671 
1672  delete heap_profiler_;
1673  heap_profiler_ = NULL;
1674  delete cpu_profiler_;
1675  cpu_profiler_ = NULL;
1676 
1677  // The default isolate is re-initializable due to legacy API.
1678  state_ = UNINITIALIZED;
1679  }
1680 }
1681 
1682 
1683 void Isolate::PushToPartialSnapshotCache(Object* obj) {
1684  int length = serialize_partial_snapshot_cache_length();
1685  int capacity = serialize_partial_snapshot_cache_capacity();
1686 
1687  if (length >= capacity) {
1688  int new_capacity = static_cast<int>((capacity + 10) * 1.2);
1689  Object** new_array = new Object*[new_capacity];
1690  for (int i = 0; i < length; i++) {
1691  new_array[i] = serialize_partial_snapshot_cache()[i];
1692  }
1693  if (capacity != 0) delete[] serialize_partial_snapshot_cache();
1694  set_serialize_partial_snapshot_cache(new_array);
1695  set_serialize_partial_snapshot_cache_capacity(new_capacity);
1696  }
1697 
1698  serialize_partial_snapshot_cache()[length] = obj;
1699  set_serialize_partial_snapshot_cache_length(length + 1);
1700 }
1701 
1702 
1703 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
1704  PerIsolateThreadData* data) {
1705  Thread::SetThreadLocal(isolate_key_, isolate);
1706  Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
1707 }
1708 
1709 
1710 Isolate::~Isolate() {
1711  TRACE_ISOLATE(destructor);
1712 
1713  // Has to be called while counters_ are still alive
1714  runtime_zone_.DeleteKeptSegment();
1715 
1716  // The entry stack must be empty when we get here,
1717  // except for the default isolate, where it can
1718  // still contain up to one entry stack item
1719  ASSERT(entry_stack_ == NULL || this == default_isolate_);
1720  ASSERT(entry_stack_ == NULL || entry_stack_->previous_item == NULL);
1721 
1722  delete entry_stack_;
1723  entry_stack_ = NULL;
1724 
1725  delete[] assembler_spare_buffer_;
1726  assembler_spare_buffer_ = NULL;
1727 
1728  delete unicode_cache_;
1729  unicode_cache_ = NULL;
1730 
1731  delete date_cache_;
1732  date_cache_ = NULL;
1733 
1734  delete[] code_stub_interface_descriptors_;
1735  code_stub_interface_descriptors_ = NULL;
1736 
1737  delete[] call_descriptors_;
1738  call_descriptors_ = NULL;
1739 
1740  delete regexp_stack_;
1741  regexp_stack_ = NULL;
1742 
1743  delete descriptor_lookup_cache_;
1744  descriptor_lookup_cache_ = NULL;
1745  delete context_slot_cache_;
1746  context_slot_cache_ = NULL;
1747  delete keyed_lookup_cache_;
1748  keyed_lookup_cache_ = NULL;
1749 
1750  delete stub_cache_;
1751  stub_cache_ = NULL;
1752  delete stats_table_;
1753  stats_table_ = NULL;
1754 
1755  delete materialized_object_store_;
1756  materialized_object_store_ = NULL;
1757 
1758  delete logger_;
1759  logger_ = NULL;
1760 
1761  delete counters_;
1762  counters_ = NULL;
1763 
1764  delete handle_scope_implementer_;
1765  handle_scope_implementer_ = NULL;
1766 
1767  delete compilation_cache_;
1768  compilation_cache_ = NULL;
1769  delete bootstrapper_;
1770  bootstrapper_ = NULL;
1771  delete inner_pointer_to_code_cache_;
1772  inner_pointer_to_code_cache_ = NULL;
1773  delete write_iterator_;
1774  write_iterator_ = NULL;
1775 
1776  delete thread_manager_;
1777  thread_manager_ = NULL;
1778 
1779  delete string_tracker_;
1780  string_tracker_ = NULL;
1781 
1782  delete memory_allocator_;
1783  memory_allocator_ = NULL;
1784  delete code_range_;
1785  code_range_ = NULL;
1786  delete global_handles_;
1787  global_handles_ = NULL;
1788  delete eternal_handles_;
1789  eternal_handles_ = NULL;
1790 
1791  delete string_stream_debug_object_cache_;
1792  string_stream_debug_object_cache_ = NULL;
1793 
1794  delete external_reference_table_;
1795  external_reference_table_ = NULL;
1796 
1797  delete random_number_generator_;
1798  random_number_generator_ = NULL;
1799 
1800 #ifdef ENABLE_DEBUGGER_SUPPORT
1801  delete debugger_;
1802  debugger_ = NULL;
1803  delete debug_;
1804  debug_ = NULL;
1805 #endif
1806 }
1807 
1808 
1809 void Isolate::InitializeThreadLocal() {
1810  thread_local_top_.isolate_ = this;
1811  thread_local_top_.Initialize();
1812 }
1813 
1814 
1815 void Isolate::PropagatePendingExceptionToExternalTryCatch() {
1816  ASSERT(has_pending_exception());
1817 
1818  bool external_caught = IsExternallyCaught();
1819  thread_local_top_.external_caught_exception_ = external_caught;
1820 
1821  if (!external_caught) return;
1822 
1823  if (thread_local_top_.pending_exception_ ==
1824  heap()->termination_exception()) {
1825  try_catch_handler()->can_continue_ = false;
1826  try_catch_handler()->has_terminated_ = true;
1827  try_catch_handler()->exception_ = heap()->null_value();
1828  } else {
1829  v8::TryCatch* handler = try_catch_handler();
1830  // At this point all non-object (failure) exceptions have
1831  // been dealt with so this shouldn't fail.
1832  ASSERT(!pending_exception()->IsFailure());
1833  ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() ||
1834  thread_local_top_.pending_message_obj_->IsTheHole());
1835  ASSERT(thread_local_top_.pending_message_script_->IsScript() ||
1836  thread_local_top_.pending_message_script_->IsTheHole());
1837  handler->can_continue_ = true;
1838  handler->has_terminated_ = false;
1839  handler->exception_ = pending_exception();
1840  // Propagate to the external try-catch only if we got an actual message.
1841  if (thread_local_top_.pending_message_obj_->IsTheHole()) return;
1842 
1843  handler->message_obj_ = thread_local_top_.pending_message_obj_;
1844  handler->message_script_ = thread_local_top_.pending_message_script_;
1845  handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_;
1846  handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_;
1847  }
1848 }
1849 
1850 
1851 void Isolate::InitializeLoggingAndCounters() {
1852  if (logger_ == NULL) {
1853  logger_ = new Logger(this);
1854  }
1855  if (counters_ == NULL) {
1856  counters_ = new Counters(this);
1857  }
1858 }
1859 
1860 
1861 void Isolate::InitializeDebugger() {
1862 #ifdef ENABLE_DEBUGGER_SUPPORT
1863  LockGuard<RecursiveMutex> lock_guard(debugger_access());
1864  if (NoBarrier_Load(&debugger_initialized_)) return;
1865  InitializeLoggingAndCounters();
1866  debug_ = new Debug(this);
1867  debugger_ = new Debugger(this);
1868  Release_Store(&debugger_initialized_, true);
1869 #endif
1870 }
1871 
1872 
1873 bool Isolate::Init(Deserializer* des) {
1874  ASSERT(state_ != INITIALIZED);
1875  TRACE_ISOLATE(init);
1876 
1877  stress_deopt_count_ = FLAG_deopt_every_n_times;
1878 
1879  has_fatal_error_ = false;
1880 
1881  use_crankshaft_ = FLAG_crankshaft
1882  && !Serializer::enabled()
1883  && CPU::SupportsCrankshaft();
1884 
1885  if (function_entry_hook() != NULL) {
1886  // When function entry hooking is in effect, we have to create the code
1887  // stubs from scratch to get entry hooks, rather than loading the previously
1888  // generated stubs from disk.
1889  // If this assert fires, the initialization path has regressed.
1890  ASSERT(des == NULL);
1891  }
1892 
1893  // The initialization process does not handle memory exhaustion.
1894  DisallowAllocationFailure disallow_allocation_failure(this);
1895 
1896  InitializeLoggingAndCounters();
1897 
1898  InitializeDebugger();
1899 
1900  memory_allocator_ = new MemoryAllocator(this);
1901  code_range_ = new CodeRange(this);
1902 
1903  // Safe after setting Heap::isolate_, and initializing StackGuard
1904  heap_.SetStackLimits();
1905 
1906 #define ASSIGN_ELEMENT(CamelName, hacker_name) \
1907  isolate_addresses_[Isolate::k##CamelName##Address] = \
1908  reinterpret_cast<Address>(hacker_name##_address());
1910 #undef ASSIGN_ELEMENT
1911 
1912  string_tracker_ = new StringTracker();
1913  string_tracker_->isolate_ = this;
1914  compilation_cache_ = new CompilationCache(this);
1915  keyed_lookup_cache_ = new KeyedLookupCache();
1916  context_slot_cache_ = new ContextSlotCache();
1917  descriptor_lookup_cache_ = new DescriptorLookupCache();
1918  unicode_cache_ = new UnicodeCache();
1919  inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
1920  write_iterator_ = new ConsStringIteratorOp();
1921  global_handles_ = new GlobalHandles(this);
1922  eternal_handles_ = new EternalHandles();
1923  bootstrapper_ = new Bootstrapper(this);
1924  handle_scope_implementer_ = new HandleScopeImplementer(this);
1925  stub_cache_ = new StubCache(this);
1926  materialized_object_store_ = new MaterializedObjectStore(this);
1927  regexp_stack_ = new RegExpStack();
1928  regexp_stack_->isolate_ = this;
1929  date_cache_ = new DateCache();
1930  code_stub_interface_descriptors_ =
1931  new CodeStubInterfaceDescriptor[CodeStub::NUMBER_OF_IDS];
1932  call_descriptors_ =
1933  new CallInterfaceDescriptor[NUMBER_OF_CALL_DESCRIPTORS];
1934  cpu_profiler_ = new CpuProfiler(this);
1935  heap_profiler_ = new HeapProfiler(heap());
1936 
1937  // Enable logging before setting up the heap
1938  logger_->SetUp(this);
1939 
1940  // Initialize other runtime facilities
1941 #if defined(USE_SIMULATOR)
1942 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS
1943  Simulator::Initialize(this);
1944 #endif
1945 #endif
1946 
1947  { // NOLINT
1948  // Ensure that the thread has a valid stack guard. The v8::Locker object
1949  // will ensure this too, but we don't have to use lockers if we are only
1950  // using one thread.
1951  ExecutionAccess lock(this);
1952  stack_guard_.InitThread(lock);
1953  }
1954 
1955  // SetUp the object heap.
1956  ASSERT(!heap_.HasBeenSetUp());
1957  if (!heap_.SetUp()) {
1958  V8::FatalProcessOutOfMemory("heap setup");
1959  return false;
1960  }
1961 
1962  deoptimizer_data_ = new DeoptimizerData(memory_allocator_);
1963 
1964  const bool create_heap_objects = (des == NULL);
1965  if (create_heap_objects && !heap_.CreateHeapObjects()) {
1966  V8::FatalProcessOutOfMemory("heap object creation");
1967  return false;
1968  }
1969 
1970  if (create_heap_objects) {
1971  // Terminate the cache array with the sentinel so we can iterate.
1972  PushToPartialSnapshotCache(heap_.undefined_value());
1973  }
1974 
1975  InitializeThreadLocal();
1976 
1977  bootstrapper_->Initialize(create_heap_objects);
1978  builtins_.SetUp(this, create_heap_objects);
1979 
1980  if (FLAG_log_internal_timer_events) {
1981  set_event_logger(Logger::LogInternalEvents);
1982  } else {
1983  set_event_logger(Logger::EmptyLogInternalEvents);
1984  }
1985 
1986  // Set default value if not yet set.
1987  // TODO(yangguo): move this to ResourceConstraints::ConfigureDefaults
1988  // once ResourceConstraints becomes an argument to the Isolate constructor.
1989  if (max_available_threads_ < 1) {
1990  // Choose the default between 1 and 4.
1991  max_available_threads_ = Max(Min(CPU::NumberOfProcessorsOnline(), 4), 1);
1992  }
1993 
1994  if (!FLAG_job_based_sweeping) {
1995  num_sweeper_threads_ =
1996  SweeperThread::NumberOfThreads(max_available_threads_);
1997  }
1998 
1999  if (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs) {
2000  PrintF("Concurrent recompilation has been disabled for tracing.\n");
2001  } else if (OptimizingCompilerThread::Enabled(max_available_threads_)) {
2002  optimizing_compiler_thread_ = new OptimizingCompilerThread(this);
2003  optimizing_compiler_thread_->Start();
2004  }
2005 
2006  if (num_sweeper_threads_ > 0) {
2007  sweeper_thread_ = new SweeperThread*[num_sweeper_threads_];
2008  for (int i = 0; i < num_sweeper_threads_; i++) {
2009  sweeper_thread_[i] = new SweeperThread(this);
2010  sweeper_thread_[i]->Start();
2011  }
2012  }
2013 
2014 #ifdef ENABLE_DEBUGGER_SUPPORT
2015  debug_->SetUp(create_heap_objects);
2016 #endif
2017 
2018  // If we are deserializing, read the state into the now-empty heap.
2019  if (!create_heap_objects) {
2020  des->Deserialize(this);
2021  }
2022  stub_cache_->Initialize();
2023 
2024  // Finish initialization of ThreadLocal after deserialization is done.
2025  clear_pending_exception();
2026  clear_pending_message();
2027  clear_scheduled_exception();
2028 
2029  // Deserializing may put strange things in the root array's copy of the
2030  // stack guard.
2031  heap_.SetStackLimits();
2032 
2033  // Quiet the heap NaN if needed on target platform.
2034  if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
2035 
2036  runtime_profiler_ = new RuntimeProfiler(this);
2037 
2038  // If we are deserializing, log non-function code objects and compiled
2039  // functions found in the snapshot.
2040  if (!create_heap_objects &&
2041  (FLAG_log_code ||
2042  FLAG_ll_prof ||
2043  FLAG_perf_jit_prof ||
2044  FLAG_perf_basic_prof ||
2045  logger_->is_logging_code_events())) {
2046  HandleScope scope(this);
2047  LOG(this, LogCodeObjects());
2048  LOG(this, LogCompiledFunctions());
2049  }
2050 
2051  // If we are profiling with the Linux perf tool, we need to disable
2052  // code relocation.
2053  if (FLAG_perf_jit_prof || FLAG_perf_basic_prof) {
2054  FLAG_compact_code_space = false;
2055  }
2056 
2057  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, embedder_data_)),
2058  Internals::kIsolateEmbedderDataOffset);
2059  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)),
2060  Internals::kIsolateRootsOffset);
2061 
2062  state_ = INITIALIZED;
2063  time_millis_at_init_ = OS::TimeCurrentMillis();
2064 
2065  if (!create_heap_objects) {
2066  // Now that the heap is consistent, it's OK to generate the code for the
2067  // deopt entry table that might have been referred to by optimized code in
2068  // the snapshot.
2069  HandleScope scope(this);
2070  Deoptimizer::EnsureCodeForDeoptimizationEntry(
2071  this,
2072  Deoptimizer::LAZY,
2074  }
2075 
2076  if (!Serializer::enabled()) {
2077  // Ensure that all stubs which need to be generated ahead of time, but
2078  // cannot be serialized into the snapshot have been generated.
2079  HandleScope scope(this);
2080  CodeStub::GenerateFPStubs(this);
2081  StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(this);
2082  StubFailureTrampolineStub::GenerateAheadOfTime(this);
2083  // Ensure interface descriptors are initialized even when stubs have been
2084  // deserialized out of the snapshot without using the graph builder.
2085  FastCloneShallowArrayStub::InstallDescriptors(this);
2086  BinaryOpICStub::InstallDescriptors(this);
2087  BinaryOpWithAllocationSiteStub::InstallDescriptors(this);
2088  CompareNilICStub::InstallDescriptors(this);
2089  ToBooleanStub::InstallDescriptors(this);
2090  ToNumberStub::InstallDescriptors(this);
2091  ArrayConstructorStubBase::InstallDescriptors(this);
2092  InternalArrayConstructorStubBase::InstallDescriptors(this);
2093  FastNewClosureStub::InstallDescriptors(this);
2094  FastNewContextStub::InstallDescriptors(this);
2095  NumberToStringStub::InstallDescriptors(this);
2096  StringAddStub::InstallDescriptors(this);
2097  RegExpConstructResultStub::InstallDescriptors(this);
2098  }
2099 
2100  CallDescriptors::InitializeForIsolate(this);
2101 
2102  initialized_from_snapshot_ = (des != NULL);
2103 
2104  return true;
2105 }
2106 
2107 
2108 // Initialized lazily to allow early
2109 // v8::V8::SetAddHistogramSampleFunction calls.
2110 StatsTable* Isolate::stats_table() {
2111  if (stats_table_ == NULL) {
2112  stats_table_ = new StatsTable;
2113  }
2114  return stats_table_;
2115 }
2116 
2117 
2118 void Isolate::Enter() {
2119  Isolate* current_isolate = NULL;
2120  PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
2121  if (current_data != NULL) {
2122  current_isolate = current_data->isolate_;
2123  ASSERT(current_isolate != NULL);
2124  if (current_isolate == this) {
2125  ASSERT(Current() == this);
2126  ASSERT(entry_stack_ != NULL);
2127  ASSERT(entry_stack_->previous_thread_data == NULL ||
2128  entry_stack_->previous_thread_data->thread_id().Equals(
2129  ThreadId::Current()));
2130  // Same thread re-enters the isolate, no need to re-init anything.
2131  entry_stack_->entry_count++;
2132  return;
2133  }
2134  }
2135 
2136  // Threads can have default isolate set into TLS as Current but not yet have
2137  // PerIsolateThreadData for it, as it requires more advanced phase of the
2138  // initialization. For example, a thread might be the one that system used for
2139  // static initializers - in this case the default isolate is set in TLS but
2140  // the thread did not yet Enter the isolate. If PerisolateThreadData is not
2141  // there, use the isolate set in TLS.
2142  if (current_isolate == NULL) {
2143  current_isolate = Isolate::UncheckedCurrent();
2144  }
2145 
2146  PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
2147  ASSERT(data != NULL);
2148  ASSERT(data->isolate_ == this);
2149 
2150  EntryStackItem* item = new EntryStackItem(current_data,
2151  current_isolate,
2152  entry_stack_);
2153  entry_stack_ = item;
2154 
2155  SetIsolateThreadLocals(this, data);
2156 
2157  // In case it's the first time some thread enters the isolate.
2158  set_thread_id(data->thread_id());
2159 }
2160 
2161 
2162 void Isolate::Exit() {
2163  ASSERT(entry_stack_ != NULL);
2164  ASSERT(entry_stack_->previous_thread_data == NULL ||
2165  entry_stack_->previous_thread_data->thread_id().Equals(
2166  ThreadId::Current()));
2167 
2168  if (--entry_stack_->entry_count > 0) return;
2169 
2170  ASSERT(CurrentPerIsolateThreadData() != NULL);
2171  ASSERT(CurrentPerIsolateThreadData()->isolate_ == this);
2172 
2173  // Pop the stack.
2174  EntryStackItem* item = entry_stack_;
2175  entry_stack_ = item->previous_item;
2176 
2177  PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
2178  Isolate* previous_isolate = item->previous_isolate;
2179 
2180  delete item;
2181 
2182  // Reinit the current thread for the isolate it was running before this one.
2183  SetIsolateThreadLocals(previous_isolate, previous_thread_data);
2184 }
2185 
2186 
2187 void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
2188  deferred->next_ = deferred_handles_head_;
2189  if (deferred_handles_head_ != NULL) {
2190  deferred_handles_head_->previous_ = deferred;
2191  }
2192  deferred_handles_head_ = deferred;
2193 }
2194 
2195 
2196 void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
2197 #ifdef DEBUG
2198  // In debug mode assert that the linked list is well-formed.
2199  DeferredHandles* deferred_iterator = deferred;
2200  while (deferred_iterator->previous_ != NULL) {
2201  deferred_iterator = deferred_iterator->previous_;
2202  }
2203  ASSERT(deferred_handles_head_ == deferred_iterator);
2204 #endif
2205  if (deferred_handles_head_ == deferred) {
2206  deferred_handles_head_ = deferred_handles_head_->next_;
2207  }
2208  if (deferred->next_ != NULL) {
2209  deferred->next_->previous_ = deferred->previous_;
2210  }
2211  if (deferred->previous_ != NULL) {
2212  deferred->previous_->next_ = deferred->next_;
2213  }
2214 }
2215 
2216 
2217 HStatistics* Isolate::GetHStatistics() {
2218  if (hstatistics() == NULL) set_hstatistics(new HStatistics());
2219  return hstatistics();
2220 }
2221 
2222 
2223 HTracer* Isolate::GetHTracer() {
2224  if (htracer() == NULL) set_htracer(new HTracer(id()));
2225  return htracer();
2226 }
2227 
2228 
2229 CodeTracer* Isolate::GetCodeTracer() {
2230  if (code_tracer() == NULL) set_code_tracer(new CodeTracer(id()));
2231  return code_tracer();
2232 }
2233 
2234 
2235 Map* Isolate::get_initial_js_array_map(ElementsKind kind) {
2236  Context* native_context = context()->native_context();
2237  Object* maybe_map_array = native_context->js_array_maps();
2238  if (!maybe_map_array->IsUndefined()) {
2239  Object* maybe_transitioned_map =
2240  FixedArray::cast(maybe_map_array)->get(kind);
2241  if (!maybe_transitioned_map->IsUndefined()) {
2242  return Map::cast(maybe_transitioned_map);
2243  }
2244  }
2245  return NULL;
2246 }
2247 
2248 
2249 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
2250  Map* root_array_map =
2251  get_initial_js_array_map(GetInitialFastElementsKind());
2252  ASSERT(root_array_map != NULL);
2253  JSObject* initial_array_proto = JSObject::cast(*initial_array_prototype());
2254 
2255  // Check that the array prototype hasn't been altered WRT empty elements.
2256  if (root_array_map->prototype() != initial_array_proto) return false;
2257  if (initial_array_proto->elements() != heap()->empty_fixed_array()) {
2258  return false;
2259  }
2260 
2261  // Check that the object prototype hasn't been altered WRT empty elements.
2262  JSObject* initial_object_proto = JSObject::cast(*initial_object_prototype());
2263  Object* root_array_map_proto = initial_array_proto->GetPrototype();
2264  if (root_array_map_proto != initial_object_proto) return false;
2265  if (initial_object_proto->elements() != heap()->empty_fixed_array()) {
2266  return false;
2267  }
2268 
2269  return initial_object_proto->GetPrototype()->IsNull();
2270 }
2271 
2272 
2274  Isolate::code_stub_interface_descriptor(int index) {
2275  return code_stub_interface_descriptors_ + index;
2276 }
2277 
2278 
2280  Isolate::call_descriptor(CallDescriptorKey index) {
2281  ASSERT(0 <= index && index < NUMBER_OF_CALL_DESCRIPTORS);
2282  return &call_descriptors_[index];
2283 }
2284 
2285 
2286 Object* Isolate::FindCodeObject(Address a) {
2287  return inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(a);
2288 }
2289 
2290 
2291 #ifdef DEBUG
2292 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \
2293 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
2294 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
2295 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
2296 #undef ISOLATE_FIELD_OFFSET
2297 #endif
2298 
2299 
2300 Handle<JSObject> Isolate::GetSymbolRegistry() {
2301  if (heap()->symbol_registry()->IsUndefined()) {
2302  Handle<Map> map = factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
2303  Handle<JSObject> registry = factory()->NewJSObjectFromMap(map);
2304  heap()->set_symbol_registry(*registry);
2305 
2306  static const char* nested[] = {
2307  "for", "for_api", "for_intern", "keyFor", "private_api", "private_intern"
2308  };
2309  for (unsigned i = 0; i < ARRAY_SIZE(nested); ++i) {
2310  Handle<String> name = factory()->InternalizeUtf8String(nested[i]);
2311  Handle<JSObject> obj = factory()->NewJSObjectFromMap(map);
2312  JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8);
2313  JSObject::SetProperty(registry, name, obj, NONE, STRICT);
2314  }
2315  }
2316  return Handle<JSObject>::cast(factory()->symbol_registry());
2317 }
2318 
2319 
2320 } } // namespace v8::internal
byte * Address
Definition: globals.h:186
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
Definition: flags.cc:269
Object * context() const
Definition: frames-inl.h:183
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
#define CHECK_NOT_EMPTY_HANDLE(isolate, call)
Definition: isolate.h:145
Failure * StackOverflow()
Definition: isolate.cc:871
static void * GetThreadLocal(LocalStorageKey key)
Handle< JSObject > NewJSObject(Handle< JSFunction > constructor, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1319
#define CHECK_EQ(expected, value)
Definition: checks.h:252
const char * ToCString(const v8::String::Utf8Value &value)
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 true
Definition: flags.cc:208
MaybeObject * pending_exception()
Definition: isolate.h:570
void PrintF(const char *format,...)
Definition: v8utils.cc:40
void PrintStack(StringStream *accumulator)
Definition: isolate.cc:686
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 map
Definition: flags.cc:350
static String * cast(Object *obj)
void ScheduleThrow(Object *exception)
Definition: isolate.cc:956
PerIsolateThreadData * FindPerThreadDataForThread(ThreadId thread_id)
Definition: isolate.cc:171
Handle< Context > GetCallingNativeContext()
Definition: isolate.cc:1382
Handle< FixedArray > NewFixedArrayWithHoles(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:62
static Smi * FromInt(int value)
Definition: objects-inl.h:1209
#define LOG(isolate, Call)
Definition: log.h:86
bool HasCaught() const
Definition: api.cc:1901
void ReportFailedAccessCheck(JSObject *receiver, v8::AccessType type)
Definition: isolate.cc:720
StackTraceOptions
Definition: v8.h:1280
void Log(Isolate *isolate)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:75
const int kDeoptTableSerializeEntryCount
Definition: serialize.h:63
bool MayNamedAccess(JSObject *receiver, Object *key, v8::AccessType type)
Definition: isolate.cc:775
T Max(T a, T b)
Definition: utils.h:227
Address get_address_from_id(AddressId id)
Definition: isolate.cc:247
void IterateDeferredHandles(ObjectVisitor *visitor)
Definition: isolate.cc:307
bool(* IndexedSecurityCallback)(Local< Object > host, uint32_t index, AccessType type, Local< Value > data)
Definition: v8.h:3418
void DoThrow(Object *exception, MessageLocation *location)
Definition: isolate.cc:1090
T & at(int i) const
Definition: list.h:90
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
Definition: flags.cc:665
Handle< JSArray > NewJSArrayWithElements(Handle< FixedArrayBase > elements, ElementsKind elements_kind, int length, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1456
Bootstrapper * bootstrapper()
Definition: isolate.h:858
static Failure * Exception()
Definition: objects-inl.h:1244
Failure * ReThrow(MaybeObject *exception)
Definition: isolate.cc:929
PerIsolateThreadData * FindPerThreadDataForThisThread()
Definition: isolate.cc:165
struct v8::internal::StaticInitializer static_initializer
virtual void Summarize(List< FrameSummary > *frames)
Definition: frames.cc:791
static Address handler(ThreadLocalTop *thread)
Definition: isolate.h:651
static Handle< Object > SetHiddenProperty(Handle< JSObject > object, Handle< Name > key, Handle< Object > value)
Definition: objects.cc:4861
#define ASSERT(condition)
Definition: checks.h:329
static PerIsolateThreadData * CurrentPerIsolateThreadData()
Definition: isolate.h:463
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback)
Definition: isolate.cc:714
static Handle< Object > SetLocalPropertyIgnoreAttributes(Handle< JSObject > object, Handle< Name > key, Handle< Object > value, PropertyAttributes attributes, ValueType value_type=OPTIMAL_REPRESENTATION, StoreMode mode=ALLOW_AS_CONSTANT, ExtensibilityCheck extensibility_check=PERFORM_EXTENSIBILITY_CHECK)
Definition: objects.cc:4141
static StackGuard * GetDefaultIsolateStackGuard()
Definition: isolate.cc:223
static Script * cast(Object *obj)
void clear_pending_exception()
Definition: isolate.h:579
static Context * cast(Object *context)
Definition: contexts.h:244
static Handle< Object > ToDetailString(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:725
#define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)
void clear_scheduled_exception()
Definition: isolate.h:634
static void UnregisterCTryCatch()
Definition: simulator-arm.h:81
#define CHECK(condition)
Definition: checks.h:75
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:196
static void SetCrashIfDefaultIsolateInitialized()
Definition: isolate.cc:182
Factory * factory()
Definition: isolate.h:995
static int GetThreadLocalInt(LocalStorageKey key)
Definition: platform.h:572
void CaptureAndSetDetailedStackTrace(Handle< JSObject > error_object)
Definition: isolate.cc:509
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
Failure * ThrowInvalidStringLength()
Definition: isolate.cc:950
static Smi * cast(Object *object)
void(* FailedAccessCheckCallback)(Local< Object > target, AccessType type, Local< Value > data)
Definition: v8.h:4046
void clear_pending_message()
Definition: isolate.h:593
StackGuard * stack_guard()
Definition: isolate.h:874
int isnan(double x)
void Add(Vector< const char > format, Vector< FmtElm > elms)
static Handle< JSMessageObject > MakeMessageObject(Isolate *isolate, const char *type, MessageLocation *loc, Vector< Handle< Object > > args, Handle< JSArray > stack_frames)
Definition: messages.cc:59
Handle< Context > global_context()
Definition: isolate.cc:1377
bool OptionalRescheduleException(bool is_bottom_call)
Definition: isolate.cc:1319
GlobalObject * global_object()
Definition: contexts.h:388
Object * receiver() const
Definition: frames-inl.h:269
V8_INLINE bool IsNull() const
Definition: v8.h:6247
HANDLE HANDLE LPSTACKFRAME64 StackFrame
Address try_catch_handler_address()
Definition: isolate.h:601
static void Abort()
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
static void EnsureDefaultIsolate()
Definition: isolate.cc:189
void ReportPendingMessages()
Definition: isolate.cc:1268
#define ISOLATE_INIT_LIST(V)
Definition: isolate.h:347
static JSGlobalProxy * cast(Object *obj)
String * hidden_string()
Definition: heap.h:1349
static Address c_entry_fp(ThreadLocalTop *thread)
Definition: isolate.h:648
#define OFFSET_OF(type, field)
Definition: globals.h:325
static void MemCopy(void *dest, const void *src, size_t size)
Definition: platform.h:399
v8::TryCatch * try_catch_handler()
Definition: isolate.h:598
static ThreadId Current()
Definition: isolate.h:170
Context * native_context()
Definition: contexts.cc:67
void ComputeLocation(MessageLocation *target)
Definition: isolate.cc:1021
static void EnterDefaultIsolate()
Definition: isolate.cc:229
MaybeObject * scheduled_exception()
Definition: isolate.h:627
void FatalProcessOutOfMemory(const char *message)
static LocalStorageKey CreateThreadLocalKey()
static Handle< JSObject > Copy(Handle< JSObject > object)
Definition: objects.cc:5636
void PrintCurrentStackTrace(FILE *out)
Definition: isolate.cc:993
void IterateThread(ThreadVisitor *v, char *t)
Definition: isolate.cc:259
void Iterate(ObjectVisitor *v)
Definition: isolate.cc:301
Handle< JSArray > CaptureCurrentStackTrace(int frame_limit, StackTrace::StackTraceOptions options)
Definition: isolate.cc:521
void RestorePendingMessageFromTryCatch(v8::TryCatch *handler)
Definition: isolate.cc:969
void Deserialize(Isolate *isolate)
Definition: serialize.cc:799
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 code(assertions) for debugging") DEFINE_bool(code_comments
static v8::Isolate * GetDefaultIsolateForLocking()
Definition: isolate.cc:241
const Register pc
int GetScriptLineNumberSafe(Handle< Script > script, int code_pos)
Definition: handles.cc:403
Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
bool has_pending_exception()
Definition: isolate.h:587
AccessType
Definition: v8.h:3395
void SetCaptureStackTraceForUncaughtExceptions(bool capture, int frame_limit, StackTrace::StackTraceOptions options)
Definition: isolate.cc:1362
Handle< JSBuiltinsObject > js_builtins_object()
Definition: isolate.h:680
static JavaScriptFrame * cast(StackFrame *frame)
Definition: frames.h:635
Failure * Throw(Object *exception, MessageLocation *location=NULL)
Definition: isolate.cc:923
#define STATIC_ASCII_VECTOR(x)
Definition: utils.h:570
Handle< Script > script() const
Definition: messages.h:77
void Release_Store(volatile Atomic32 *ptr, Atomic32 value)
friend class ThreadId
Definition: isolate.h:1350
int id() const
Definition: isolate.h:1093
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static JSArray * cast(Object *obj)
Context * context()
Definition: isolate.h:557
Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr)
#define ISOLATE_INIT_EXECUTE(type, name, initial_value)
int GetScriptLineNumber(Handle< Script > script, int code_pos)
Definition: handles.cc:363
Failure * PromoteScheduledException()
Definition: isolate.cc:985
virtual void VisitThread(Isolate *isolate, ThreadLocalTop *top)=0
void PrintMentionedObjectCache(Isolate *isolate)
MessageLocation GetMessageLocation()
Definition: isolate.cc:1301
static void WriteToFlat(String *source, sinkchar *sink, int from, int to)
Definition: objects.cc:8635
Handle< String > InternalizeOneByteString(Vector< const uint8_t > str)
Definition: factory.cc:232
bool is_null() const
Definition: handles.h:81
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C)
Definition: isolate.h:154
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:103
bool IsNumber() const
Definition: api.cc:2416
static SmartArrayPointer< char > GetLocalizedMessage(Isolate *isolate, Handle< Object > data)
Definition: messages.cc:188
static AccessCheckInfo * cast(Object *obj)
Handle< JSArray > CaptureSimpleStackTrace(Handle< JSObject > error_object, Handle< Object > caller, int limit)
Definition: isolate.cc:441
ElementsKind GetInitialFastElementsKind()
static void SetThreadLocal(LocalStorageKey key, void *value)
Handle< String > StackTraceString()
Definition: isolate.cc:360
Handle< String > ToString(Isolate *isolate)
void set_pending_exception(MaybeObject *exception)
Definition: isolate.h:575
Handle< Object > GetScriptNameOrSourceURL(Handle< Script > script)
Definition: handles.cc:474
static void PrintError(const char *format,...)
bool(* NamedSecurityCallback)(Local< Object > host, Local< Value > key, AccessType type, Local< Value > data)
Definition: v8.h:3408
const int kHandleBlockSize
Definition: api.h:616
#define TRACE_ISOLATE(tag)
Definition: isolate.cc:1492
static void ClearMentionedObjectCache(Isolate *isolate)
bool MayIndexedAccess(JSObject *receiver, uint32_t index, v8::AccessType type)
Definition: isolate.cc:825
DefaultIsolateStatus
Definition: isolate.cc:138
static FixedArray * cast(Object *obj)
void InitializeLoggingAndCounters()
Definition: isolate.cc:1851
void UnregisterTryCatchHandler(v8::TryCatch *that)
Definition: isolate.cc:351
Failure * TerminateExecution()
Definition: isolate.cc:900
char * ArchiveThread(char *to)
Definition: isolate.cc:1404
Failure * ThrowIllegalOperation()
Definition: isolate.cc:944
static ThreadId Invalid()
Definition: isolate.h:173
static Handle< String > GetStackTraceLine(Handle< Object > recv, Handle< JSFunction > fun, Handle< Object > pos, Handle< Object > is_global)
Definition: execution.cc:880
void RegisterTryCatchHandler(v8::TryCatch *that)
Definition: isolate.cc:339
bool is_catchable_by_javascript(MaybeObject *exception)
Definition: isolate.h:640
int32_t Atomic32
Definition: atomicops.h:66
char * RestoreThread(char *from)
Definition: isolate.cc:1415
void OutputToFile(FILE *out)
HeapObject * obj
bool has_scheduled_exception()
Definition: isolate.h:631
static Thread::LocalStorageKey thread_local_key
Definition: assert-scope.h:109
Handle< Context > native_context()
Definition: isolate.cc:1372
static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address)
Definition: simulator-arm.h:77
static void ReportMessage(Isolate *isolate, MessageLocation *loc, Handle< Object > message)
Definition: messages.cc:100
bool ShouldReportException(bool *can_be_caught_externally, bool catchable_by_javascript)
Definition: isolate.cc:1039
T Min(T a, T b)
Definition: utils.h:234
Object * GetHiddenProperty(Name *key)
Definition: objects.cc:4831
static int NewElementsCapacity(int old_capacity)
Definition: objects.h:2467
ThreadLocalTop * thread_local_top()
Definition: isolate.h:879
#define ARRAY_SIZE(a)
Definition: globals.h:333
static const char *const kStackOverflowMessage
Definition: isolate.h:822
static void SetThreadLocalInt(LocalStorageKey key, int value)
Definition: platform.h:576
static JSObject * cast(Object *obj)
#define ISOLATE_INIT_ARRAY_LIST(V)
Definition: isolate.h:336
JSFunction * function() const
Definition: frames-inl.h:284
Handle< JSArray > NewJSArray(ElementsKind elements_kind, int length, int capacity, ArrayStorageAllocationMode mode=INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1437
void CancelTerminateExecution()
Definition: isolate.cc:906
#define TRY_CATCH_FROM_ADDRESS(try_catch_address)
Definition: simulator-arm.h:63
#define ASSIGN_ELEMENT(CamelName, hacker_name)
static JSFunction * cast(Object *obj)