v8  3.14.5(node0.10.28)
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 "debug.h"
37 #include "deoptimizer.h"
38 #include "heap-profiler.h"
39 #include "hydrogen.h"
40 #include "isolate.h"
41 #include "lithium-allocator.h"
42 #include "log.h"
43 #include "messages.h"
44 #include "platform.h"
45 #include "regexp-stack.h"
46 #include "runtime-profiler.h"
47 #include "scopeinfo.h"
48 #include "serialize.h"
49 #include "simulator.h"
50 #include "spaces.h"
51 #include "stub-cache.h"
52 #include "version.h"
53 #include "vm-state-inl.h"
54 
55 
56 namespace v8 {
57 namespace internal {
58 
59 Atomic32 ThreadId::highest_thread_id_ = 0;
60 
61 int ThreadId::AllocateThreadId() {
62  int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
63  return new_id;
64 }
65 
66 
67 int ThreadId::GetCurrentThreadId() {
68  int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
69  if (thread_id == 0) {
70  thread_id = AllocateThreadId();
71  Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
72  }
73  return thread_id;
74 }
75 
76 
77 ThreadLocalTop::ThreadLocalTop() {
78  InitializeInternal();
79  // This flag may be set using v8::V8::IgnoreOutOfMemoryException()
80  // before an isolate is initialized. The initialize methods below do
81  // not touch it to preserve its value.
82  ignore_out_of_memory_ = false;
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_ = 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  pending_message_obj_ = NULL;
109  pending_message_script_ = NULL;
110  scheduled_exception_ = NULL;
111 }
112 
113 
114 void ThreadLocalTop::Initialize() {
115  InitializeInternal();
116 #ifdef USE_SIMULATOR
117 #ifdef V8_TARGET_ARCH_ARM
118  simulator_ = Simulator::current(isolate_);
119 #elif V8_TARGET_ARCH_MIPS
120  simulator_ = Simulator::current(isolate_);
121 #endif
122 #endif
123  thread_id_ = ThreadId::Current();
124 }
125 
126 
127 v8::TryCatch* ThreadLocalTop::TryCatchHandler() {
128  return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address());
129 }
130 
131 
132 // Create a dummy thread that will wait forever on a semaphore. The only
133 // purpose for this thread is to have some stack area to save essential data
134 // into for use by a stacks only core dump (aka minidump).
136  public:
137  char* data() {
138  if (data_ready_semaphore_ != NULL) {
139  // Initial access is guarded until the data has been published.
140  data_ready_semaphore_->Wait();
141  delete data_ready_semaphore_;
142  data_ready_semaphore_ = NULL;
143  }
144  return data_;
145  }
146 
147  unsigned length() {
148  if (data_ready_semaphore_ != NULL) {
149  // Initial access is guarded until the data has been published.
150  data_ready_semaphore_->Wait();
151  delete data_ready_semaphore_;
152  data_ready_semaphore_ = NULL;
153  }
154  return length_;
155  }
156 
157  // Stop the PreallocatedMemoryThread and release its resources.
158  void StopThread() {
159  keep_running_ = false;
160  wait_for_ever_semaphore_->Signal();
161 
162  // Wait for the thread to terminate.
163  Join();
164 
165  if (data_ready_semaphore_ != NULL) {
166  delete data_ready_semaphore_;
167  data_ready_semaphore_ = NULL;
168  }
169 
170  delete wait_for_ever_semaphore_;
171  wait_for_ever_semaphore_ = NULL;
172  }
173 
174  protected:
175  // When the thread starts running it will allocate a fixed number of bytes
176  // on the stack and publish the location of this memory for others to use.
177  void Run() {
178  EmbeddedVector<char, 15 * 1024> local_buffer;
179 
180  // Initialize the buffer with a known good value.
181  OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
182  local_buffer.length());
183 
184  // Publish the local buffer and signal its availability.
185  data_ = local_buffer.start();
186  length_ = local_buffer.length();
187  data_ready_semaphore_->Signal();
188 
189  while (keep_running_) {
190  // This thread will wait here until the end of time.
191  wait_for_ever_semaphore_->Wait();
192  }
193 
194  // Make sure we access the buffer after the wait to remove all possibility
195  // of it being optimized away.
196  OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
197  local_buffer.length());
198  }
199 
200 
201  private:
203  : Thread("v8:PreallocMem"),
204  keep_running_(true),
205  wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
206  data_ready_semaphore_(OS::CreateSemaphore(0)),
207  data_(NULL),
208  length_(0) {
209  }
210 
211  // Used to make sure that the thread keeps looping even for spurious wakeups.
212  bool keep_running_;
213 
214  // This semaphore is used by the PreallocatedMemoryThread to wait for ever.
215  Semaphore* wait_for_ever_semaphore_;
216  // Semaphore to signal that the data has been initialized.
217  Semaphore* data_ready_semaphore_;
218 
219  // Location and size of the preallocated memory block.
220  char* data_;
221  unsigned length_;
222 
223  friend class Isolate;
224 
226 };
227 
228 
229 void Isolate::PreallocatedMemoryThreadStart() {
230  if (preallocated_memory_thread_ != NULL) return;
231  preallocated_memory_thread_ = new PreallocatedMemoryThread();
232  preallocated_memory_thread_->Start();
233 }
234 
235 
236 void Isolate::PreallocatedMemoryThreadStop() {
237  if (preallocated_memory_thread_ == NULL) return;
238  preallocated_memory_thread_->StopThread();
239  // Done with the thread entirely.
240  delete preallocated_memory_thread_;
241  preallocated_memory_thread_ = NULL;
242 }
243 
244 
246  ASSERT(free_list_.next_ == &free_list_);
247  ASSERT(free_list_.previous_ == &free_list_);
248  PreallocatedStorage* free_chunk =
249  reinterpret_cast<PreallocatedStorage*>(new char[size]);
250  free_list_.next_ = free_list_.previous_ = free_chunk;
251  free_chunk->next_ = free_chunk->previous_ = &free_list_;
252  free_chunk->size_ = size - sizeof(PreallocatedStorage);
253  preallocated_storage_preallocated_ = true;
254 }
255 
256 
258  if (!preallocated_storage_preallocated_) {
259  return FreeStoreAllocationPolicy().New(size);
260  }
261  ASSERT(free_list_.next_ != &free_list_);
262  ASSERT(free_list_.previous_ != &free_list_);
263 
264  size = (size + kPointerSize - 1) & ~(kPointerSize - 1);
265  // Search for exact fit.
266  for (PreallocatedStorage* storage = free_list_.next_;
267  storage != &free_list_;
268  storage = storage->next_) {
269  if (storage->size_ == size) {
270  storage->Unlink();
271  storage->LinkTo(&in_use_list_);
272  return reinterpret_cast<void*>(storage + 1);
273  }
274  }
275  // Search for first fit.
276  for (PreallocatedStorage* storage = free_list_.next_;
277  storage != &free_list_;
278  storage = storage->next_) {
279  if (storage->size_ >= size + sizeof(PreallocatedStorage)) {
280  storage->Unlink();
281  storage->LinkTo(&in_use_list_);
282  PreallocatedStorage* left_over =
283  reinterpret_cast<PreallocatedStorage*>(
284  reinterpret_cast<char*>(storage + 1) + size);
285  left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage);
286  ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) ==
287  storage->size_);
288  storage->size_ = size;
289  left_over->LinkTo(&free_list_);
290  return reinterpret_cast<void*>(storage + 1);
291  }
292  }
293  // Allocation failure.
294  ASSERT(false);
295  return NULL;
296 }
297 
298 
299 // We don't attempt to coalesce.
301  if (p == NULL) {
302  return;
303  }
304  if (!preallocated_storage_preallocated_) {
305  FreeStoreAllocationPolicy::Delete(p);
306  return;
307  }
308  PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1;
309  ASSERT(storage->next_->previous_ == storage);
310  ASSERT(storage->previous_->next_ == storage);
311  storage->Unlink();
312  storage->LinkTo(&free_list_);
313 }
314 
315 Isolate* Isolate::default_isolate_ = NULL;
316 Thread::LocalStorageKey Isolate::isolate_key_;
317 Thread::LocalStorageKey Isolate::thread_id_key_;
318 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
319 Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
320 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
321 
322 
323 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
324  ThreadId thread_id) {
325  ASSERT(!thread_id.Equals(ThreadId::Invalid()));
326  PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
327  {
328  ScopedLock lock(process_wide_mutex_);
329  ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL);
330  thread_data_table_->Insert(per_thread);
331  ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
332  }
333  return per_thread;
334 }
335 
336 
337 Isolate::PerIsolateThreadData*
338  Isolate::FindOrAllocatePerThreadDataForThisThread() {
339  ThreadId thread_id = ThreadId::Current();
340  PerIsolateThreadData* per_thread = NULL;
341  {
342  ScopedLock lock(process_wide_mutex_);
343  per_thread = thread_data_table_->Lookup(this, thread_id);
344  if (per_thread == NULL) {
345  per_thread = AllocatePerIsolateThreadData(thread_id);
346  }
347  }
348  return per_thread;
349 }
350 
351 
353  ThreadId thread_id = ThreadId::Current();
354  PerIsolateThreadData* per_thread = NULL;
355  {
356  ScopedLock lock(process_wide_mutex_);
357  per_thread = thread_data_table_->Lookup(this, thread_id);
358  }
359  return per_thread;
360 }
361 
362 
364  ScopedLock lock(process_wide_mutex_);
365  if (default_isolate_ == NULL) {
366  isolate_key_ = Thread::CreateThreadLocalKey();
367  thread_id_key_ = Thread::CreateThreadLocalKey();
368  per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
369  thread_data_table_ = new Isolate::ThreadDataTable();
370  default_isolate_ = new Isolate();
371  }
372  // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
373  // because a non-null thread data may be already set.
374  if (Thread::GetThreadLocal(isolate_key_) == NULL) {
375  Thread::SetThreadLocal(isolate_key_, default_isolate_);
376  }
377 }
378 
382  }
384 
385 #ifdef ENABLE_DEBUGGER_SUPPORT
386 Debugger* Isolate::GetDefaultIsolateDebugger() {
388  return default_isolate_->debugger();
389 }
390 #endif
391 
392 
395  return default_isolate_->stack_guard();
396 }
397 
398 
401  ASSERT(default_isolate_ != NULL);
402 
404  // If not yet in default isolate - enter it.
405  if (data == NULL || data->isolate() != default_isolate_) {
406  default_isolate_->Enter();
407  }
408 }
409 
410 
411 Isolate* Isolate::GetDefaultIsolateForLocking() {
413  return default_isolate_;
414 }
415 
416 
418  return isolate_addresses_[id];
419 }
420 
421 
422 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) {
423  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
424  Iterate(v, thread);
425  return thread_storage + sizeof(ThreadLocalTop);
426 }
427 
428 
430  v->VisitThread(this, thread_local_top());
431 }
432 
433 
435  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
436  v->VisitThread(this, thread);
437 }
438 
439 
440 void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
441  // Visit the roots from the top for a given thread.
442  Object* pending;
443  // The pending exception can sometimes be a failure. We can't show
444  // that to the GC, which only understands objects.
445  if (thread->pending_exception_->ToObject(&pending)) {
446  v->VisitPointer(&pending);
447  thread->pending_exception_ = pending; // In case GC updated it.
448  }
449  v->VisitPointer(&(thread->pending_message_obj_));
450  v->VisitPointer(BitCast<Object**>(&(thread->pending_message_script_)));
451  v->VisitPointer(BitCast<Object**>(&(thread->context_)));
452  Object* scheduled;
453  if (thread->scheduled_exception_->ToObject(&scheduled)) {
454  v->VisitPointer(&scheduled);
455  thread->scheduled_exception_ = scheduled;
456  }
457 
458  for (v8::TryCatch* block = thread->TryCatchHandler();
459  block != NULL;
460  block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
461  v->VisitPointer(BitCast<Object**>(&(block->exception_)));
462  v->VisitPointer(BitCast<Object**>(&(block->message_)));
463  }
464 
465  // Iterate over pointers on native execution stack.
466  for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
467  it.frame()->Iterate(v);
468  }
469 
470  // Iterate pointers in live lookup results.
471  thread->top_lookup_result_->Iterate(v);
472 }
473 
474 
475 void Isolate::Iterate(ObjectVisitor* v) {
476  ThreadLocalTop* current_t = thread_local_top();
477  Iterate(v, current_t);
478 }
479 
480 void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) {
481  for (DeferredHandles* deferred = deferred_handles_head_;
482  deferred != NULL;
483  deferred = deferred->next_) {
484  deferred->Iterate(visitor);
485  }
486 }
487 
488 
490  // The ARM simulator has a separate JS stack. We therefore register
491  // the C++ try catch handler with the simulator and get back an
492  // address that can be used for comparisons with addresses into the
493  // JS stack. When running without the simulator, the address
494  // returned will be the address of the C++ try catch handler itself.
495  Address address = reinterpret_cast<Address>(
496  SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
497  thread_local_top()->set_try_catch_handler_address(address);
498 }
499 
500 
502  ASSERT(thread_local_top()->TryCatchHandler() == that);
503  thread_local_top()->set_try_catch_handler_address(
504  reinterpret_cast<Address>(that->next_));
505  thread_local_top()->catcher_ = NULL;
507 }
508 
509 
511  if (stack_trace_nesting_level_ == 0) {
512  stack_trace_nesting_level_++;
513  HeapStringAllocator allocator;
515  StringStream accumulator(&allocator);
516  incomplete_message_ = &accumulator;
517  PrintStack(&accumulator);
518  Handle<String> stack_trace = accumulator.ToString();
519  incomplete_message_ = NULL;
520  stack_trace_nesting_level_ = 0;
521  return stack_trace;
522  } else if (stack_trace_nesting_level_ == 1) {
523  stack_trace_nesting_level_++;
525  "\n\nAttempt to print stack while printing stack (double fault)\n");
527  "If you are lucky you may find a partial stack dump on stdout.\n\n");
528  incomplete_message_->OutputToStdOut();
529  return factory()->empty_symbol();
530  } else {
531  OS::Abort();
532  // Unreachable
533  return factory()->empty_symbol();
534  }
535 }
536 
537 
538 void Isolate::PushStackTraceAndDie(unsigned int magic,
539  Object* object,
540  Map* map,
541  unsigned int magic2) {
542  const int kMaxStackTraceSize = 8192;
544  char buffer[kMaxStackTraceSize];
545  int length = Min(kMaxStackTraceSize - 1, trace->length());
546  String::WriteToFlat(*trace, buffer, 0, length);
547  buffer[length] = '\0';
548  OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n",
549  magic, magic2,
550  static_cast<void*>(object), static_cast<void*>(map),
551  buffer);
552  OS::Abort();
553 }
554 
555 
557  if (capture_stack_trace_for_uncaught_exceptions_) {
558  // Capture stack trace for a detailed exception message.
559  Handle<String> key = factory()->hidden_stack_trace_symbol();
561  stack_trace_for_uncaught_exceptions_frame_limit_,
562  stack_trace_for_uncaught_exceptions_options_);
563  JSObject::SetHiddenProperty(error_object, key, stack_trace);
564  }
565 }
566 
567 
569  int frame_limit, StackTrace::StackTraceOptions options) {
570  // Ensure no negative values.
571  int limit = Max(frame_limit, 0);
572  Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
573 
574  Handle<String> column_key = factory()->LookupAsciiSymbol("column");
575  Handle<String> line_key = factory()->LookupAsciiSymbol("lineNumber");
576  Handle<String> script_key = factory()->LookupAsciiSymbol("scriptName");
577  Handle<String> name_or_source_url_key =
578  factory()->LookupAsciiSymbol("nameOrSourceURL");
579  Handle<String> script_name_or_source_url_key =
580  factory()->LookupAsciiSymbol("scriptNameOrSourceURL");
581  Handle<String> function_key = factory()->LookupAsciiSymbol("functionName");
582  Handle<String> eval_key = factory()->LookupAsciiSymbol("isEval");
583  Handle<String> constructor_key =
584  factory()->LookupAsciiSymbol("isConstructor");
585 
586  StackTraceFrameIterator it(this);
587  int frames_seen = 0;
588  while (!it.done() && (frames_seen < limit)) {
589  JavaScriptFrame* frame = it.frame();
590  // Set initial size to the maximum inlining level + 1 for the outermost
591  // function.
593  frame->Summarize(&frames);
594  for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
595  // Create a JSObject to hold the information for the StackFrame.
596  Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
597 
598  Handle<JSFunction> fun = frames[i].function();
599  Handle<Script> script(Script::cast(fun->shared()->script()));
600 
601  if (options & StackTrace::kLineNumber) {
602  int script_line_offset = script->line_offset()->value();
603  int position = frames[i].code()->SourcePosition(frames[i].pc());
604  int line_number = GetScriptLineNumber(script, position);
605  // line_number is already shifted by the script_line_offset.
606  int relative_line_number = line_number - script_line_offset;
607  if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
608  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
609  int start = (relative_line_number == 0) ? 0 :
610  Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
611  int column_offset = position - start;
612  if (relative_line_number == 0) {
613  // For the case where the code is on the same line as the script
614  // tag.
615  column_offset += script->column_offset()->value();
616  }
618  this,
620  stack_frame, column_key,
621  Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE));
622  }
624  this,
626  stack_frame, line_key,
627  Handle<Smi>(Smi::FromInt(line_number + 1)), NONE));
628  }
629 
630  if (options & StackTrace::kScriptName) {
631  Handle<Object> script_name(script->name(), this);
634  stack_frame, script_key, script_name, NONE));
635  }
636 
637  if (options & StackTrace::kScriptNameOrSourceURL) {
638  Handle<Object> script_name(script->name(), this);
639  Handle<JSValue> script_wrapper = GetScriptWrapper(script);
640  Handle<Object> property = GetProperty(script_wrapper,
641  name_or_source_url_key);
642  ASSERT(property->IsJSFunction());
643  Handle<JSFunction> method = Handle<JSFunction>::cast(property);
644  bool caught_exception;
645  Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
646  NULL, &caught_exception);
647  if (caught_exception) {
648  result = factory()->undefined_value();
649  }
652  stack_frame, script_name_or_source_url_key,
653  result, NONE));
654  }
655 
656  if (options & StackTrace::kFunctionName) {
657  Handle<Object> fun_name(fun->shared()->name(), this);
658  if (fun_name->ToBoolean()->IsFalse()) {
659  fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
660  }
663  stack_frame, function_key, fun_name, NONE));
664  }
665 
666  if (options & StackTrace::kIsEval) {
667  int type = Smi::cast(script->compilation_type())->value();
668  Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
669  factory()->true_value() : factory()->false_value();
672  stack_frame, eval_key, is_eval, NONE));
673  }
674 
675  if (options & StackTrace::kIsConstructor) {
676  Handle<Object> is_constructor = (frames[i].is_constructor()) ?
677  factory()->true_value() : factory()->false_value();
680  stack_frame, constructor_key,
681  is_constructor, NONE));
682  }
683 
684  FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
685  frames_seen++;
686  }
687  it.Advance();
688  }
689 
690  stack_trace->set_length(Smi::FromInt(frames_seen));
691  return stack_trace;
692 }
693 
694 
696  if (stack_trace_nesting_level_ == 0) {
697  stack_trace_nesting_level_++;
698 
699  StringAllocator* allocator;
700  if (preallocated_message_space_ == NULL) {
701  allocator = new HeapStringAllocator();
702  } else {
703  allocator = preallocated_message_space_;
704  }
705 
707  StringStream accumulator(allocator);
708  incomplete_message_ = &accumulator;
709  PrintStack(&accumulator);
710  accumulator.OutputToStdOut();
712  accumulator.Log();
713  incomplete_message_ = NULL;
714  stack_trace_nesting_level_ = 0;
715  if (preallocated_message_space_ == NULL) {
716  // Remove the HeapStringAllocator created above.
717  delete allocator;
718  }
719  } else if (stack_trace_nesting_level_ == 1) {
720  stack_trace_nesting_level_++;
722  "\n\nAttempt to print stack while printing stack (double fault)\n");
724  "If you are lucky you may find a partial stack dump on stdout.\n\n");
725  incomplete_message_->OutputToStdOut();
726  }
727 }
728 
729 
730 static void PrintFrames(StringStream* accumulator,
731  StackFrame::PrintMode mode) {
732  StackFrameIterator it;
733  for (int i = 0; !it.done(); it.Advance()) {
734  it.frame()->Print(accumulator, mode, i++);
735  }
736 }
737 
738 
739 void Isolate::PrintStack(StringStream* accumulator) {
740  if (!IsInitialized()) {
741  accumulator->Add(
742  "\n==== Stack trace is not available ==========================\n\n");
743  accumulator->Add(
744  "\n==== Isolate for the thread is not initialized =============\n\n");
745  return;
746  }
747  // The MentionedObjectCache is not GC-proof at the moment.
748  AssertNoAllocation nogc;
749  ASSERT(StringStream::IsMentionedObjectCacheClear());
750 
751  // Avoid printing anything if there are no frames.
752  if (c_entry_fp(thread_local_top()) == 0) return;
753 
754  accumulator->Add(
755  "\n==== Stack trace ============================================\n\n");
756  PrintFrames(accumulator, StackFrame::OVERVIEW);
757 
758  accumulator->Add(
759  "\n==== Details ================================================\n\n");
760  PrintFrames(accumulator, StackFrame::DETAILS);
761 
762  accumulator->PrintMentionedObjectCache();
763  accumulator->Add("=====================\n\n");
764 }
765 
766 
769  thread_local_top()->failed_access_check_callback_ = callback;
770 }
771 
772 
774  if (!thread_local_top()->failed_access_check_callback_) return;
775 
776  ASSERT(receiver->IsAccessCheckNeeded());
777  ASSERT(context());
778 
779  // Get the data object from access check info.
780  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
781  if (!constructor->shared()->IsApiFunction()) return;
782  Object* data_obj =
783  constructor->shared()->get_api_func_data()->access_check_info();
784  if (data_obj == heap_.undefined_value()) return;
785 
786  HandleScope scope;
787  Handle<JSObject> receiver_handle(receiver);
788  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
789  { VMState state(this, EXTERNAL);
790  thread_local_top()->failed_access_check_callback_(
791  v8::Utils::ToLocal(receiver_handle),
792  type,
793  v8::Utils::ToLocal(data));
794  }
795 }
796 
797 
800 };
801 
802 
803 static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
804  JSObject* receiver,
805  v8::AccessType type) {
806  // During bootstrapping, callback functions are not enabled yet.
807  if (isolate->bootstrapper()->IsActive()) return YES;
808 
809  if (receiver->IsJSGlobalProxy()) {
810  Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context();
811  if (!receiver_context->IsContext()) return NO;
812 
813  // Get the native context of current top context.
814  // avoid using Isolate::native_context() because it uses Handle.
815  Context* native_context =
816  isolate->context()->global_object()->native_context();
817  if (receiver_context == native_context) return YES;
818 
819  if (Context::cast(receiver_context)->security_token() ==
820  native_context->security_token())
821  return YES;
822  }
823 
824  return UNKNOWN;
825 }
826 
827 
829  v8::AccessType type) {
830  ASSERT(receiver->IsAccessCheckNeeded());
831 
832  // The callers of this method are not expecting a GC.
833  AssertNoAllocation no_gc;
834 
835  // Skip checks for hidden properties access. Note, we do not
836  // require existence of a context in this case.
837  if (key == heap_.hidden_symbol()) return true;
838 
839  // Check for compatibility between the security tokens in the
840  // current lexical context and the accessed object.
841  ASSERT(context());
842 
843  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
844  if (decision != UNKNOWN) return decision == YES;
845 
846  // Get named access check callback
847  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
848  if (!constructor->shared()->IsApiFunction()) return false;
849 
850  Object* data_obj =
851  constructor->shared()->get_api_func_data()->access_check_info();
852  if (data_obj == heap_.undefined_value()) return false;
853 
854  Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
855  v8::NamedSecurityCallback callback =
856  v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
857 
858  if (!callback) return false;
859 
860  HandleScope scope(this);
861  Handle<JSObject> receiver_handle(receiver, this);
862  Handle<Object> key_handle(key, this);
863  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
864  LOG(this, ApiNamedSecurityCheck(key));
865  bool result = false;
866  {
867  // Leaving JavaScript.
868  VMState state(this, EXTERNAL);
869  result = callback(v8::Utils::ToLocal(receiver_handle),
870  v8::Utils::ToLocal(key_handle),
871  type,
872  v8::Utils::ToLocal(data));
873  }
874  return result;
875 }
876 
877 
879  uint32_t index,
880  v8::AccessType type) {
881  ASSERT(receiver->IsAccessCheckNeeded());
882  // Check for compatibility between the security tokens in the
883  // current lexical context and the accessed object.
884  ASSERT(context());
885 
886  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
887  if (decision != UNKNOWN) return decision == YES;
888 
889  // Get indexed access check callback
890  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
891  if (!constructor->shared()->IsApiFunction()) return false;
892 
893  Object* data_obj =
894  constructor->shared()->get_api_func_data()->access_check_info();
895  if (data_obj == heap_.undefined_value()) return false;
896 
897  Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
898  v8::IndexedSecurityCallback callback =
899  v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
900 
901  if (!callback) return false;
902 
903  HandleScope scope(this);
904  Handle<JSObject> receiver_handle(receiver, this);
905  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
906  LOG(this, ApiIndexedSecurityCheck(index));
907  bool result = false;
908  {
909  // Leaving JavaScript.
910  VMState state(this, EXTERNAL);
911  result = callback(v8::Utils::ToLocal(receiver_handle),
912  index,
913  type,
914  v8::Utils::ToLocal(data));
915  }
916  return result;
917 }
918 
919 
920 const char* const Isolate::kStackOverflowMessage =
921  "Uncaught RangeError: Maximum call stack size exceeded";
922 
923 
925  HandleScope scope;
926  Handle<String> key = factory()->stack_overflow_symbol();
927  Handle<JSObject> boilerplate =
929  Handle<Object> exception = Copy(boilerplate);
930  // TODO(1240995): To avoid having to call JavaScript code to compute
931  // the message for stack overflow exceptions which is very likely to
932  // double fault with another stack overflow exception, we use a
933  // precomputed message.
934  DoThrow(*exception, NULL);
935  return Failure::Exception();
936 }
937 
938 
940  DoThrow(heap_.termination_exception(), NULL);
941  return Failure::Exception();
942 }
943 
944 
945 Failure* Isolate::Throw(Object* exception, MessageLocation* location) {
946  DoThrow(exception, location);
947  return Failure::Exception();
948 }
949 
950 
951 Failure* Isolate::ReThrow(MaybeObject* exception) {
952  bool can_be_caught_externally = false;
953  bool catchable_by_javascript = is_catchable_by_javascript(exception);
954  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
955 
956  thread_local_top()->catcher_ = can_be_caught_externally ?
958 
959  // Set the exception being re-thrown.
960  set_pending_exception(exception);
961  if (exception->IsFailure()) return exception->ToFailureUnchecked();
962  return Failure::Exception();
963 }
964 
965 
967  return Throw(heap_.illegal_access_symbol());
968 }
969 
970 
971 void Isolate::ScheduleThrow(Object* exception) {
972  // When scheduling a throw we first throw the exception to get the
973  // error reporting if it is uncaught before rescheduling it.
974  Throw(exception);
975  thread_local_top()->scheduled_exception_ = pending_exception();
976  thread_local_top()->external_caught_exception_ = false;
978 }
979 
980 
982  MaybeObject* thrown = scheduled_exception();
984  // Re-throw the exception to avoid getting repeated error reporting.
985  return ReThrow(thrown);
986 }
987 
988 
990  StackTraceFrameIterator it(this);
991  while (!it.done()) {
992  HandleScope scope;
993  // Find code position if recorded in relocation info.
994  JavaScriptFrame* frame = it.frame();
995  int pos = frame->LookupCode()->SourcePosition(frame->pc());
996  Handle<Object> pos_obj(Smi::FromInt(pos));
997  // Fetch function and receiver.
999  Handle<Object> recv(frame->receiver());
1000  // Advance to the next JavaScript frame and determine if the
1001  // current frame is the top-level frame.
1002  it.Advance();
1003  Handle<Object> is_top_level = it.done()
1004  ? factory()->true_value()
1005  : factory()->false_value();
1006  // Generate and print stack trace line.
1007  Handle<String> line =
1008  Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
1009  if (line->length() > 0) {
1010  line->PrintOn(out);
1011  fprintf(out, "\n");
1012  }
1013  }
1014 }
1015 
1016 
1018  *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
1019  StackTraceFrameIterator it(this);
1020  if (!it.done()) {
1021  JavaScriptFrame* frame = it.frame();
1022  JSFunction* fun = JSFunction::cast(frame->function());
1023  Object* script = fun->shared()->script();
1024  if (script->IsScript() &&
1025  !(Script::cast(script)->source()->IsUndefined())) {
1026  int pos = frame->LookupCode()->SourcePosition(frame->pc());
1027  // Compute the location from the function and the reloc info.
1028  Handle<Script> casted_script(Script::cast(script));
1029  *target = MessageLocation(casted_script, pos, pos + 1);
1030  }
1031  }
1032 }
1033 
1034 
1035 bool Isolate::ShouldReportException(bool* can_be_caught_externally,
1036  bool catchable_by_javascript) {
1037  // Find the top-most try-catch handler.
1038  StackHandler* handler =
1039  StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1040  while (handler != NULL && !handler->is_catch()) {
1041  handler = handler->next();
1042  }
1043 
1044  // Get the address of the external handler so we can compare the address to
1045  // determine which one is closer to the top of the stack.
1046  Address external_handler_address =
1047  thread_local_top()->try_catch_handler_address();
1048 
1049  // The exception has been externally caught if and only if there is
1050  // an external handler which is on top of the top-most try-catch
1051  // handler.
1052  *can_be_caught_externally = external_handler_address != NULL &&
1053  (handler == NULL || handler->address() > external_handler_address ||
1054  !catchable_by_javascript);
1055 
1056  if (*can_be_caught_externally) {
1057  // Only report the exception if the external handler is verbose.
1058  return try_catch_handler()->is_verbose_;
1059  } else {
1060  // Report the exception if it isn't caught by JavaScript code.
1061  return handler == NULL;
1062  }
1063 }
1064 
1065 
1066 bool Isolate::IsErrorObject(Handle<Object> obj) {
1067  if (!obj->IsJSObject()) return false;
1068 
1069  String* error_key = *(factory()->LookupAsciiSymbol("$Error"));
1070  Object* error_constructor =
1071  js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
1072 
1073  for (Object* prototype = *obj; !prototype->IsNull();
1074  prototype = prototype->GetPrototype()) {
1075  if (!prototype->IsJSObject()) return false;
1076  if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
1077  return true;
1078  }
1079  }
1080  return false;
1081 }
1082 
1083 
1084 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
1086 
1087  HandleScope scope;
1088  Handle<Object> exception_handle(exception);
1089 
1090  // Determine reporting and whether the exception is caught externally.
1091  bool catchable_by_javascript = is_catchable_by_javascript(exception);
1092  bool can_be_caught_externally = false;
1093  bool should_report_exception =
1094  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
1095  bool report_exception = catchable_by_javascript && should_report_exception;
1096  bool try_catch_needs_message =
1097  can_be_caught_externally && try_catch_handler()->capture_message_;
1098  bool bootstrapping = bootstrapper()->IsActive();
1099 
1100 #ifdef ENABLE_DEBUGGER_SUPPORT
1101  // Notify debugger of exception.
1102  if (catchable_by_javascript) {
1103  debugger_->OnException(exception_handle, report_exception);
1104  }
1105 #endif
1106 
1107  // Generate the message if required.
1108  if (report_exception || try_catch_needs_message) {
1109  MessageLocation potential_computed_location;
1110  if (location == NULL) {
1111  // If no location was specified we use a computed one instead.
1112  ComputeLocation(&potential_computed_location);
1113  location = &potential_computed_location;
1114  }
1115  // It's not safe to try to make message objects or collect stack traces
1116  // while the bootstrapper is active since the infrastructure may not have
1117  // been properly initialized.
1118  if (!bootstrapping) {
1119  Handle<String> stack_trace;
1120  if (FLAG_trace_exception) stack_trace = StackTraceString();
1121  Handle<JSArray> stack_trace_object;
1122  if (capture_stack_trace_for_uncaught_exceptions_) {
1123  if (IsErrorObject(exception_handle)) {
1124  // We fetch the stack trace that corresponds to this error object.
1125  String* key = heap()->hidden_stack_trace_symbol();
1126  Object* stack_property =
1127  JSObject::cast(*exception_handle)->GetHiddenProperty(key);
1128  // Property lookup may have failed. In this case it's probably not
1129  // a valid Error object.
1130  if (stack_property->IsJSArray()) {
1131  stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
1132  }
1133  }
1134  if (stack_trace_object.is_null()) {
1135  // Not an error object, we capture at throw site.
1136  stack_trace_object = CaptureCurrentStackTrace(
1137  stack_trace_for_uncaught_exceptions_frame_limit_,
1138  stack_trace_for_uncaught_exceptions_options_);
1139  }
1140  }
1142  "uncaught_exception",
1143  location,
1144  HandleVector<Object>(&exception_handle, 1),
1145  stack_trace,
1146  stack_trace_object);
1147  thread_local_top()->pending_message_obj_ = *message_obj;
1148  if (location != NULL) {
1149  thread_local_top()->pending_message_script_ = *location->script();
1150  thread_local_top()->pending_message_start_pos_ = location->start_pos();
1151  thread_local_top()->pending_message_end_pos_ = location->end_pos();
1152  }
1153  } else if (location != NULL && !location->script().is_null()) {
1154  // We are bootstrapping and caught an error where the location is set
1155  // and we have a script for the location.
1156  // In this case we could have an extension (or an internal error
1157  // somewhere) and we print out the line number at which the error occured
1158  // to the console for easier debugging.
1159  int line_number = GetScriptLineNumberSafe(location->script(),
1160  location->start_pos());
1161  if (exception->IsString()) {
1163  "Extension or internal compilation error: %s in %s at line %d.\n",
1164  *String::cast(exception)->ToCString(),
1165  *String::cast(location->script()->name())->ToCString(),
1166  line_number + 1);
1167  } else {
1169  "Extension or internal compilation error in %s at line %d.\n",
1170  *String::cast(location->script()->name())->ToCString(),
1171  line_number + 1);
1172  }
1173  }
1174  }
1175 
1176  // Save the message for reporting if the the exception remains uncaught.
1177  thread_local_top()->has_pending_message_ = report_exception;
1178 
1179  // Do not forget to clean catcher_ if currently thrown exception cannot
1180  // be caught. If necessary, ReThrow will update the catcher.
1181  thread_local_top()->catcher_ = can_be_caught_externally ?
1182  try_catch_handler() : NULL;
1183 
1184  set_pending_exception(*exception_handle);
1185 }
1186 
1187 
1190 
1191  if ((thread_local_top()->catcher_ == NULL) ||
1192  (try_catch_handler() != thread_local_top()->catcher_)) {
1193  // When throwing the exception, we found no v8::TryCatch
1194  // which should care about this exception.
1195  return false;
1196  }
1197 
1199  return true;
1200  }
1201 
1202  // Get the address of the external handler so we can compare the address to
1203  // determine which one is closer to the top of the stack.
1204  Address external_handler_address =
1205  thread_local_top()->try_catch_handler_address();
1206  ASSERT(external_handler_address != NULL);
1207 
1208  // The exception has been externally caught if and only if there is
1209  // an external handler which is on top of the top-most try-finally
1210  // handler.
1211  // There should be no try-catch blocks as they would prohibit us from
1212  // finding external catcher in the first place (see catcher_ check above).
1213  //
1214  // Note, that finally clause would rethrow an exception unless it's
1215  // aborted by jumps in control flow like return, break, etc. and we'll
1216  // have another chances to set proper v8::TryCatch.
1217  StackHandler* handler =
1218  StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1219  while (handler != NULL && handler->address() < external_handler_address) {
1220  ASSERT(!handler->is_catch());
1221  if (handler->is_finally()) return false;
1222 
1223  handler = handler->next();
1224  }
1225 
1226  return true;
1227 }
1228 
1229 
1232  PropagatePendingExceptionToExternalTryCatch();
1233 
1234  // If the pending exception is OutOfMemoryException set out_of_memory in
1235  // the native context. Note: We have to mark the native context here
1236  // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
1237  // set it.
1238  HandleScope scope;
1239  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
1241  } else if (thread_local_top_.pending_exception_ ==
1242  heap()->termination_exception()) {
1243  // Do nothing: if needed, the exception has been already propagated to
1244  // v8::TryCatch.
1245  } else {
1246  if (thread_local_top_.has_pending_message_) {
1247  thread_local_top_.has_pending_message_ = false;
1248  if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
1249  HandleScope scope;
1250  Handle<Object> message_obj(thread_local_top_.pending_message_obj_);
1251  if (thread_local_top_.pending_message_script_ != NULL) {
1252  Handle<Script> script(thread_local_top_.pending_message_script_);
1253  int start_pos = thread_local_top_.pending_message_start_pos_;
1254  int end_pos = thread_local_top_.pending_message_end_pos_;
1255  MessageLocation location(script, start_pos, end_pos);
1256  MessageHandler::ReportMessage(this, &location, message_obj);
1257  } else {
1258  MessageHandler::ReportMessage(this, NULL, message_obj);
1259  }
1260  }
1261  }
1262  }
1264 }
1265 
1266 
1268  FLAG_trace_exception = flag; // TODO(isolates): This is an unfortunate use.
1269 }
1270 
1271 
1272 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
1274  PropagatePendingExceptionToExternalTryCatch();
1275 
1276  // Always reschedule out of memory exceptions.
1277  if (!is_out_of_memory()) {
1278  bool is_termination_exception =
1279  pending_exception() == heap_.termination_exception();
1280 
1281  // Do not reschedule the exception if this is the bottom call.
1282  bool clear_exception = is_bottom_call;
1283 
1284  if (is_termination_exception) {
1285  if (is_bottom_call) {
1286  thread_local_top()->external_caught_exception_ = false;
1288  return false;
1289  }
1290  } else if (thread_local_top()->external_caught_exception_) {
1291  // If the exception is externally caught, clear it if there are no
1292  // JavaScript frames on the way to the C++ frame that has the
1293  // external handler.
1295  Address external_handler_address =
1296  thread_local_top()->try_catch_handler_address();
1298  if (it.done() || (it.frame()->sp() > external_handler_address)) {
1299  clear_exception = true;
1300  }
1301  }
1302 
1303  // Clear the exception if needed.
1304  if (clear_exception) {
1305  thread_local_top()->external_caught_exception_ = false;
1307  return false;
1308  }
1309  }
1310 
1311  // Reschedule the exception.
1312  thread_local_top()->scheduled_exception_ = pending_exception();
1314  return true;
1315 }
1316 
1317 
1319  bool capture,
1320  int frame_limit,
1322  capture_stack_trace_for_uncaught_exceptions_ = capture;
1323  stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
1324  stack_trace_for_uncaught_exceptions_options_ = options;
1325 }
1326 
1327 
1329  if (has_pending_exception()) {
1330  MaybeObject* e = pending_exception();
1331  if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1332  return true;
1333  }
1334  }
1335  if (has_scheduled_exception()) {
1336  MaybeObject* e = scheduled_exception();
1337  if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1338  return true;
1339  }
1340  }
1341  return false;
1342 }
1343 
1344 
1346  GlobalObject* global = thread_local_top()->context_->global_object();
1347  return Handle<Context>(global->native_context());
1348 }
1349 
1350 
1352  GlobalObject* global = thread_local_top()->context_->global_object();
1353  return Handle<Context>(global->global_context());
1354 }
1355 
1356 
1359 #ifdef ENABLE_DEBUGGER_SUPPORT
1360  if (debug_->InDebugger()) {
1361  while (!it.done()) {
1362  JavaScriptFrame* frame = it.frame();
1363  Context* context = Context::cast(frame->context());
1364  if (context->native_context() == *debug_->debug_context()) {
1365  it.Advance();
1366  } else {
1367  break;
1368  }
1369  }
1370  }
1371 #endif // ENABLE_DEBUGGER_SUPPORT
1372  if (it.done()) return Handle<Context>::null();
1373  JavaScriptFrame* frame = it.frame();
1374  Context* context = Context::cast(frame->context());
1375  return Handle<Context>(context->native_context());
1376 }
1377 
1378 
1379 char* Isolate::ArchiveThread(char* to) {
1380  if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
1382  }
1383  memcpy(to, reinterpret_cast<char*>(thread_local_top()),
1384  sizeof(ThreadLocalTop));
1385  InitializeThreadLocal();
1389  return to + sizeof(ThreadLocalTop);
1390 }
1391 
1392 
1393 char* Isolate::RestoreThread(char* from) {
1394  memcpy(reinterpret_cast<char*>(thread_local_top()), from,
1395  sizeof(ThreadLocalTop));
1396  // This might be just paranoia, but it seems to be needed in case a
1397  // thread_local_top_ is restored on a separate OS thread.
1398 #ifdef USE_SIMULATOR
1399 #ifdef V8_TARGET_ARCH_ARM
1400  thread_local_top()->simulator_ = Simulator::current(this);
1401 #elif V8_TARGET_ARCH_MIPS
1402  thread_local_top()->simulator_ = Simulator::current(this);
1403 #endif
1404 #endif
1405  if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
1407  }
1408  ASSERT(context() == NULL || context()->IsContext());
1409  return from + sizeof(ThreadLocalTop);
1410 }
1411 
1412 
1413 Isolate::ThreadDataTable::ThreadDataTable()
1414  : list_(NULL) {
1415 }
1416 
1417 
1418 Isolate::PerIsolateThreadData*
1419  Isolate::ThreadDataTable::Lookup(Isolate* isolate,
1420  ThreadId thread_id) {
1421  for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
1422  if (data->Matches(isolate, thread_id)) return data;
1423  }
1424  return NULL;
1425 }
1426 
1427 
1428 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
1429  if (list_ != NULL) list_->prev_ = data;
1430  data->next_ = list_;
1431  list_ = data;
1432 }
1433 
1434 
1435 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
1436  if (list_ == data) list_ = data->next_;
1437  if (data->next_ != NULL) data->next_->prev_ = data->prev_;
1438  if (data->prev_ != NULL) data->prev_->next_ = data->next_;
1439  delete data;
1440 }
1441 
1442 
1443 void Isolate::ThreadDataTable::Remove(Isolate* isolate,
1444  ThreadId thread_id) {
1445  PerIsolateThreadData* data = Lookup(isolate, thread_id);
1446  if (data != NULL) {
1447  Remove(data);
1448  }
1449 }
1450 
1451 
1452 void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
1453  PerIsolateThreadData* data = list_;
1454  while (data != NULL) {
1455  PerIsolateThreadData* next = data->next_;
1456  if (data->isolate() == isolate) Remove(data);
1457  data = next;
1458  }
1459 }
1460 
1461 
1462 #ifdef DEBUG
1463 #define TRACE_ISOLATE(tag) \
1464  do { \
1465  if (FLAG_trace_isolates) { \
1466  PrintF("Isolate %p " #tag "\n", reinterpret_cast<void*>(this)); \
1467  } \
1468  } while (false)
1469 #else
1470 #define TRACE_ISOLATE(tag)
1471 #endif
1472 
1473 
1474 Isolate::Isolate()
1475  : state_(UNINITIALIZED),
1476  embedder_data_(NULL),
1477  entry_stack_(NULL),
1478  stack_trace_nesting_level_(0),
1479  incomplete_message_(NULL),
1480  preallocated_memory_thread_(NULL),
1481  preallocated_message_space_(NULL),
1482  bootstrapper_(NULL),
1483  runtime_profiler_(NULL),
1484  compilation_cache_(NULL),
1485  counters_(NULL),
1486  code_range_(NULL),
1487  // Must be initialized early to allow v8::SetResourceConstraints calls.
1488  break_access_(OS::CreateMutex()),
1489  debugger_initialized_(false),
1490  // Must be initialized early to allow v8::Debug calls.
1491  debugger_access_(OS::CreateMutex()),
1492  logger_(NULL),
1493  stats_table_(NULL),
1494  stub_cache_(NULL),
1495  deoptimizer_data_(NULL),
1496  capture_stack_trace_for_uncaught_exceptions_(false),
1497  stack_trace_for_uncaught_exceptions_frame_limit_(0),
1498  stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
1499  transcendental_cache_(NULL),
1500  memory_allocator_(NULL),
1501  keyed_lookup_cache_(NULL),
1502  context_slot_cache_(NULL),
1503  descriptor_lookup_cache_(NULL),
1504  handle_scope_implementer_(NULL),
1505  unicode_cache_(NULL),
1506  runtime_zone_(this),
1507  in_use_list_(0),
1508  free_list_(0),
1509  preallocated_storage_preallocated_(false),
1510  inner_pointer_to_code_cache_(NULL),
1511  write_input_buffer_(NULL),
1512  global_handles_(NULL),
1513  context_switcher_(NULL),
1514  thread_manager_(NULL),
1515  fp_stubs_generated_(false),
1516  has_installed_extensions_(false),
1517  string_tracker_(NULL),
1518  regexp_stack_(NULL),
1519  date_cache_(NULL),
1520  context_exit_happened_(false),
1521  deferred_handles_head_(NULL),
1522  optimizing_compiler_thread_(this) {
1523  TRACE_ISOLATE(constructor);
1524 
1525  memset(isolate_addresses_, 0,
1526  sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
1527 
1528  heap_.isolate_ = this;
1529  stack_guard_.isolate_ = this;
1530 
1531  // ThreadManager is initialized early to support locking an isolate
1532  // before it is entered.
1533  thread_manager_ = new ThreadManager();
1534  thread_manager_->isolate_ = this;
1535 
1536 #if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
1537  defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
1538  simulator_initialized_ = false;
1539  simulator_i_cache_ = NULL;
1540  simulator_redirection_ = NULL;
1541 #endif
1542 
1543 #ifdef DEBUG
1544  // heap_histograms_ initializes itself.
1545  memset(&js_spill_information_, 0, sizeof(js_spill_information_));
1546  memset(code_kind_statistics_, 0,
1547  sizeof(code_kind_statistics_[0]) * Code::NUMBER_OF_KINDS);
1548 #endif
1549 
1550 #ifdef ENABLE_DEBUGGER_SUPPORT
1551  debug_ = NULL;
1552  debugger_ = NULL;
1553 #endif
1554 
1555  handle_scope_data_.Initialize();
1556 
1557 #define ISOLATE_INIT_EXECUTE(type, name, initial_value) \
1558  name##_ = (initial_value);
1560 #undef ISOLATE_INIT_EXECUTE
1561 
1562 #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length) \
1563  memset(name##_, 0, sizeof(type) * length);
1565 #undef ISOLATE_INIT_ARRAY_EXECUTE
1566 }
1567 
1568 void Isolate::TearDown() {
1569  TRACE_ISOLATE(tear_down);
1570 
1571  // Temporarily set this isolate as current so that various parts of
1572  // the isolate can access it in their destructors without having a
1573  // direct pointer. We don't use Enter/Exit here to avoid
1574  // initializing the thread data.
1575  PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
1576  Isolate* saved_isolate = UncheckedCurrent();
1577  SetIsolateThreadLocals(this, NULL);
1578 
1579  Deinit();
1580 
1581  { ScopedLock lock(process_wide_mutex_);
1582  thread_data_table_->RemoveAllThreads(this);
1583  }
1584 
1585  if (serialize_partial_snapshot_cache_ != NULL) {
1586  delete[] serialize_partial_snapshot_cache_;
1587  serialize_partial_snapshot_cache_ = NULL;
1588  }
1589 
1590  if (!IsDefaultIsolate()) {
1591  delete this;
1592  }
1593 
1594  // Restore the previous current isolate.
1595  SetIsolateThreadLocals(saved_isolate, saved_data);
1596 }
1597 
1598 
1599 void Isolate::Deinit() {
1600  if (state_ == INITIALIZED) {
1601  TRACE_ISOLATE(deinit);
1602 
1603  if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Stop();
1604 
1605  if (FLAG_hydrogen_stats) HStatistics::Instance()->Print();
1606 
1607  // We must stop the logger before we tear down other components.
1608  logger_->EnsureTickerStopped();
1609 
1610  delete deoptimizer_data_;
1611  deoptimizer_data_ = NULL;
1612  if (FLAG_preemption) {
1613  v8::Locker locker;
1615  }
1616  builtins_.TearDown();
1617  bootstrapper_->TearDown();
1618 
1619  // Remove the external reference to the preallocated stack memory.
1620  delete preallocated_message_space_;
1621  preallocated_message_space_ = NULL;
1622  PreallocatedMemoryThreadStop();
1623 
1624  HeapProfiler::TearDown();
1625  CpuProfiler::TearDown();
1626  if (runtime_profiler_ != NULL) {
1627  runtime_profiler_->TearDown();
1628  delete runtime_profiler_;
1629  runtime_profiler_ = NULL;
1630  }
1631  heap_.TearDown();
1632  logger_->TearDown();
1633 
1634  // The default isolate is re-initializable due to legacy API.
1635  state_ = UNINITIALIZED;
1636  }
1637 }
1638 
1639 
1640 void Isolate::PushToPartialSnapshotCache(Object* obj) {
1641  int length = serialize_partial_snapshot_cache_length();
1642  int capacity = serialize_partial_snapshot_cache_capacity();
1643 
1644  if (length >= capacity) {
1645  int new_capacity = static_cast<int>((capacity + 10) * 1.2);
1646  Object** new_array = new Object*[new_capacity];
1647  for (int i = 0; i < length; i++) {
1648  new_array[i] = serialize_partial_snapshot_cache()[i];
1649  }
1650  if (capacity != 0) delete[] serialize_partial_snapshot_cache();
1651  set_serialize_partial_snapshot_cache(new_array);
1652  set_serialize_partial_snapshot_cache_capacity(new_capacity);
1653  }
1654 
1655  serialize_partial_snapshot_cache()[length] = obj;
1656  set_serialize_partial_snapshot_cache_length(length + 1);
1657 }
1658 
1659 
1660 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
1661  PerIsolateThreadData* data) {
1662  Thread::SetThreadLocal(isolate_key_, isolate);
1663  Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
1664 }
1665 
1666 
1667 Isolate::~Isolate() {
1668  TRACE_ISOLATE(destructor);
1669 
1670  // Has to be called while counters_ are still alive.
1671  runtime_zone_.DeleteKeptSegment();
1672 
1673  delete[] assembler_spare_buffer_;
1674  assembler_spare_buffer_ = NULL;
1675 
1676  delete unicode_cache_;
1677  unicode_cache_ = NULL;
1678 
1679  delete date_cache_;
1680  date_cache_ = NULL;
1681 
1682  delete regexp_stack_;
1683  regexp_stack_ = NULL;
1684 
1685  delete descriptor_lookup_cache_;
1686  descriptor_lookup_cache_ = NULL;
1687  delete context_slot_cache_;
1688  context_slot_cache_ = NULL;
1689  delete keyed_lookup_cache_;
1690  keyed_lookup_cache_ = NULL;
1691 
1692  delete transcendental_cache_;
1693  transcendental_cache_ = NULL;
1694  delete stub_cache_;
1695  stub_cache_ = NULL;
1696  delete stats_table_;
1697  stats_table_ = NULL;
1698 
1699  delete logger_;
1700  logger_ = NULL;
1701 
1702  delete counters_;
1703  counters_ = NULL;
1704 
1705  delete handle_scope_implementer_;
1706  handle_scope_implementer_ = NULL;
1707  delete break_access_;
1708  break_access_ = NULL;
1709  delete debugger_access_;
1710  debugger_access_ = NULL;
1711 
1712  delete compilation_cache_;
1713  compilation_cache_ = NULL;
1714  delete bootstrapper_;
1715  bootstrapper_ = NULL;
1716  delete inner_pointer_to_code_cache_;
1717  inner_pointer_to_code_cache_ = NULL;
1718  delete write_input_buffer_;
1719  write_input_buffer_ = NULL;
1720 
1721  delete context_switcher_;
1722  context_switcher_ = NULL;
1723  delete thread_manager_;
1724  thread_manager_ = NULL;
1725 
1726  delete string_tracker_;
1727  string_tracker_ = NULL;
1728 
1729  delete memory_allocator_;
1730  memory_allocator_ = NULL;
1731  delete code_range_;
1732  code_range_ = NULL;
1733  delete global_handles_;
1734  global_handles_ = NULL;
1735 
1736  delete external_reference_table_;
1737  external_reference_table_ = NULL;
1738 
1739 #ifdef ENABLE_DEBUGGER_SUPPORT
1740  delete debugger_;
1741  debugger_ = NULL;
1742  delete debug_;
1743  debug_ = NULL;
1744 #endif
1745 }
1746 
1747 
1748 void Isolate::InitializeThreadLocal() {
1749  thread_local_top_.isolate_ = this;
1750  thread_local_top_.Initialize();
1751 }
1752 
1753 
1754 void Isolate::PropagatePendingExceptionToExternalTryCatch() {
1755  ASSERT(has_pending_exception());
1756 
1757  bool external_caught = IsExternallyCaught();
1758  thread_local_top_.external_caught_exception_ = external_caught;
1759 
1760  if (!external_caught) return;
1761 
1762  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
1763  // Do not propagate OOM exception: we should kill VM asap.
1764  } else if (thread_local_top_.pending_exception_ ==
1765  heap()->termination_exception()) {
1766  try_catch_handler()->can_continue_ = false;
1767  try_catch_handler()->exception_ = heap()->null_value();
1768  } else {
1769  // At this point all non-object (failure) exceptions have
1770  // been dealt with so this shouldn't fail.
1771  ASSERT(!pending_exception()->IsFailure());
1772  try_catch_handler()->can_continue_ = true;
1773  try_catch_handler()->exception_ = pending_exception();
1774  if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
1775  try_catch_handler()->message_ = thread_local_top_.pending_message_obj_;
1776  }
1777  }
1778 }
1779 
1780 
1781 void Isolate::InitializeLoggingAndCounters() {
1782  if (logger_ == NULL) {
1783  logger_ = new Logger;
1784  }
1785  if (counters_ == NULL) {
1786  counters_ = new Counters;
1787  }
1788 }
1789 
1790 
1791 void Isolate::InitializeDebugger() {
1792 #ifdef ENABLE_DEBUGGER_SUPPORT
1793  ScopedLock lock(debugger_access_);
1794  if (NoBarrier_Load(&debugger_initialized_)) return;
1795  InitializeLoggingAndCounters();
1796  debug_ = new Debug(this);
1797  debugger_ = new Debugger(this);
1798  Release_Store(&debugger_initialized_, true);
1799 #endif
1800 }
1801 
1802 
1803 bool Isolate::Init(Deserializer* des) {
1804  ASSERT(state_ != INITIALIZED);
1805  ASSERT(Isolate::Current() == this);
1806  TRACE_ISOLATE(init);
1807 
1808  // The initialization process does not handle memory exhaustion.
1809  DisallowAllocationFailure disallow_allocation_failure;
1810 
1811  InitializeLoggingAndCounters();
1812 
1813  InitializeDebugger();
1814 
1815  memory_allocator_ = new MemoryAllocator(this);
1816  code_range_ = new CodeRange(this);
1817 
1818  // Safe after setting Heap::isolate_, initializing StackGuard and
1819  // ensuring that Isolate::Current() == this.
1820  heap_.SetStackLimits();
1821 
1822 #define ASSIGN_ELEMENT(CamelName, hacker_name) \
1823  isolate_addresses_[Isolate::k##CamelName##Address] = \
1824  reinterpret_cast<Address>(hacker_name##_address());
1826 #undef C
1827 
1828  string_tracker_ = new StringTracker();
1829  string_tracker_->isolate_ = this;
1830  compilation_cache_ = new CompilationCache(this);
1831  transcendental_cache_ = new TranscendentalCache();
1832  keyed_lookup_cache_ = new KeyedLookupCache();
1833  context_slot_cache_ = new ContextSlotCache();
1834  descriptor_lookup_cache_ = new DescriptorLookupCache();
1835  unicode_cache_ = new UnicodeCache();
1836  inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
1837  write_input_buffer_ = new StringInputBuffer();
1838  global_handles_ = new GlobalHandles(this);
1839  bootstrapper_ = new Bootstrapper();
1840  handle_scope_implementer_ = new HandleScopeImplementer(this);
1841  stub_cache_ = new StubCache(this, runtime_zone());
1842  regexp_stack_ = new RegExpStack();
1843  regexp_stack_->isolate_ = this;
1844  date_cache_ = new DateCache();
1845 
1846  // Enable logging before setting up the heap
1847  logger_->SetUp();
1848 
1849  CpuProfiler::SetUp();
1850  HeapProfiler::SetUp();
1851 
1852  // Initialize other runtime facilities
1853 #if defined(USE_SIMULATOR)
1854 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
1855  Simulator::Initialize(this);
1856 #endif
1857 #endif
1858 
1859  { // NOLINT
1860  // Ensure that the thread has a valid stack guard. The v8::Locker object
1861  // will ensure this too, but we don't have to use lockers if we are only
1862  // using one thread.
1863  ExecutionAccess lock(this);
1864  stack_guard_.InitThread(lock);
1865  }
1866 
1867  // SetUp the object heap.
1868  const bool create_heap_objects = (des == NULL);
1869  ASSERT(!heap_.HasBeenSetUp());
1870  if (!heap_.SetUp(create_heap_objects)) {
1871  V8::SetFatalError();
1872  return false;
1873  }
1874 
1875  if (create_heap_objects) {
1876  // Terminate the cache array with the sentinel so we can iterate.
1877  PushToPartialSnapshotCache(heap_.undefined_value());
1878  }
1879 
1880  InitializeThreadLocal();
1881 
1882  bootstrapper_->Initialize(create_heap_objects);
1883  builtins_.SetUp(create_heap_objects);
1884 
1885  // Only preallocate on the first initialization.
1886  if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
1887  // Start the thread which will set aside some memory.
1888  PreallocatedMemoryThreadStart();
1889  preallocated_message_space_ =
1891  preallocated_memory_thread_->data(),
1892  preallocated_memory_thread_->length());
1893  PreallocatedStorageInit(preallocated_memory_thread_->length() / 4);
1894  }
1895 
1896  if (FLAG_preemption) {
1897  v8::Locker locker;
1899  }
1900 
1901 #ifdef ENABLE_DEBUGGER_SUPPORT
1902  debug_->SetUp(create_heap_objects);
1903 #endif
1904 
1905  // If we are deserializing, read the state into the now-empty heap.
1906  if (!create_heap_objects) {
1907  des->Deserialize();
1908  }
1909  stub_cache_->Initialize();
1910 
1911  // Finish initialization of ThreadLocal after deserialization is done.
1912  clear_pending_exception();
1913  clear_pending_message();
1914  clear_scheduled_exception();
1915 
1916  // Deserializing may put strange things in the root array's copy of the
1917  // stack guard.
1918  heap_.SetStackLimits();
1919 
1920  // Quiet the heap NaN if needed on target platform.
1921  if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
1922 
1923  deoptimizer_data_ = new DeoptimizerData;
1924  runtime_profiler_ = new RuntimeProfiler(this);
1925  runtime_profiler_->SetUp();
1926 
1927  // If we are deserializing, log non-function code objects and compiled
1928  // functions found in the snapshot.
1929  if (create_heap_objects &&
1930  (FLAG_log_code || FLAG_ll_prof || logger_->is_logging_code_events())) {
1931  HandleScope scope;
1932  LOG(this, LogCodeObjects());
1933  LOG(this, LogCompiledFunctions());
1934  }
1935 
1936  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, state_)),
1937  Internals::kIsolateStateOffset);
1938  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, embedder_data_)),
1939  Internals::kIsolateEmbedderDataOffset);
1940  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)),
1941  Internals::kIsolateRootsOffset);
1942 
1943  state_ = INITIALIZED;
1944  time_millis_at_init_ = OS::TimeCurrentMillis();
1945  if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Start();
1946  return true;
1947 }
1948 
1949 
1950 // Initialized lazily to allow early
1951 // v8::V8::SetAddHistogramSampleFunction calls.
1952 StatsTable* Isolate::stats_table() {
1953  if (stats_table_ == NULL) {
1954  stats_table_ = new StatsTable;
1955  }
1956  return stats_table_;
1957 }
1958 
1959 
1960 void Isolate::Enter() {
1961  Isolate* current_isolate = NULL;
1962  PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
1963  if (current_data != NULL) {
1964  current_isolate = current_data->isolate_;
1965  ASSERT(current_isolate != NULL);
1966  if (current_isolate == this) {
1967  ASSERT(Current() == this);
1968  ASSERT(entry_stack_ != NULL);
1969  ASSERT(entry_stack_->previous_thread_data == NULL ||
1970  entry_stack_->previous_thread_data->thread_id().Equals(
1971  ThreadId::Current()));
1972  // Same thread re-enters the isolate, no need to re-init anything.
1973  entry_stack_->entry_count++;
1974  return;
1975  }
1976  }
1977 
1978  // Threads can have default isolate set into TLS as Current but not yet have
1979  // PerIsolateThreadData for it, as it requires more advanced phase of the
1980  // initialization. For example, a thread might be the one that system used for
1981  // static initializers - in this case the default isolate is set in TLS but
1982  // the thread did not yet Enter the isolate. If PerisolateThreadData is not
1983  // there, use the isolate set in TLS.
1984  if (current_isolate == NULL) {
1985  current_isolate = Isolate::UncheckedCurrent();
1986  }
1987 
1988  PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
1989  ASSERT(data != NULL);
1990  ASSERT(data->isolate_ == this);
1991 
1992  EntryStackItem* item = new EntryStackItem(current_data,
1993  current_isolate,
1994  entry_stack_);
1995  entry_stack_ = item;
1996 
1997  SetIsolateThreadLocals(this, data);
1998 
1999  // In case it's the first time some thread enters the isolate.
2000  set_thread_id(data->thread_id());
2001 }
2002 
2003 
2004 void Isolate::Exit() {
2005  ASSERT(entry_stack_ != NULL);
2006  ASSERT(entry_stack_->previous_thread_data == NULL ||
2007  entry_stack_->previous_thread_data->thread_id().Equals(
2008  ThreadId::Current()));
2009 
2010  if (--entry_stack_->entry_count > 0) return;
2011 
2012  ASSERT(CurrentPerIsolateThreadData() != NULL);
2013  ASSERT(CurrentPerIsolateThreadData()->isolate_ == this);
2014 
2015  // Pop the stack.
2016  EntryStackItem* item = entry_stack_;
2017  entry_stack_ = item->previous_item;
2018 
2019  PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
2020  Isolate* previous_isolate = item->previous_isolate;
2021 
2022  delete item;
2023 
2024  // Reinit the current thread for the isolate it was running before this one.
2025  SetIsolateThreadLocals(previous_isolate, previous_thread_data);
2026 }
2027 
2028 
2029 void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
2030  deferred->next_ = deferred_handles_head_;
2031  if (deferred_handles_head_ != NULL) {
2032  deferred_handles_head_->previous_ = deferred;
2033  }
2034  deferred_handles_head_ = deferred;
2035 }
2036 
2037 
2038 void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
2039 #ifdef DEBUG
2040  // In debug mode assert that the linked list is well-formed.
2041  DeferredHandles* deferred_iterator = deferred;
2042  while (deferred_iterator->previous_ != NULL) {
2043  deferred_iterator = deferred_iterator->previous_;
2044  }
2045  ASSERT(deferred_handles_head_ == deferred_iterator);
2046 #endif
2047  if (deferred_handles_head_ == deferred) {
2048  deferred_handles_head_ = deferred_handles_head_->next_;
2049  }
2050  if (deferred->next_ != NULL) {
2051  deferred->next_->previous_ = deferred->previous_;
2052  }
2053  if (deferred->previous_ != NULL) {
2054  deferred->previous_->next_ = deferred->next_;
2055  }
2056 }
2057 
2058 
2059 #ifdef DEBUG
2060 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \
2061 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
2062 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
2063 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
2064 #undef ISOLATE_FIELD_OFFSET
2065 #endif
2066 
2067 } } // namespace v8::internal
byte * Address
Definition: globals.h:157
Object * context() const
Definition: frames-inl.h:163
void TraceException(bool flag)
Definition: isolate.cc:1267
#define CHECK_NOT_EMPTY_HANDLE(isolate, call)
Definition: isolate.h:128
Failure * StackOverflow()
Definition: isolate.cc:924
static void * GetThreadLocal(LocalStorageKey key)
Handle< JSObject > NewJSObject(Handle< JSFunction > constructor, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:904
Object * function() const
Definition: frames-inl.h:231
#define CHECK_EQ(expected, value)
Definition: checks.h:219
const char * ToCString(const v8::String::Utf8Value &value)
static Handle< Object > TryCall(Handle< JSFunction > func, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *caught_exception)
Definition: execution.cc:192
MaybeObject * pending_exception()
Definition: isolate.h:542
static void IsolateEnteredJS(Isolate *isolate)
static String * cast(Object *obj)
void ScheduleThrow(Object *exception)
Definition: isolate.cc:971
Handle< Context > GetCallingNativeContext()
Definition: isolate.cc:1357
StateTag current_vm_state()
Definition: isolate.h:1003
static Handle< JSMessageObject > MakeMessageObject(const char *type, MessageLocation *loc, Vector< Handle< Object > > args, Handle< String > stack_trace, Handle< JSArray > stack_frames)
Definition: messages.cc:58
static Smi * FromInt(int value)
Definition: objects-inl.h:981
#define LOG(isolate, Call)
Definition: log.h:81
void ReportFailedAccessCheck(JSObject *receiver, v8::AccessType type)
Definition: isolate.cc:773
StackTraceOptions
Definition: v8.h:769
Handle< JSArray > NewJSArray(int capacity, ElementsKind elements_kind=TERMINAL_FAST_ELEMENTS_KIND, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:937
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
bool MayNamedAccess(JSObject *receiver, Object *key, v8::AccessType type)
Definition: isolate.cc:828
T Max(T a, T b)
Definition: utils.h:222
Address get_address_from_id(AddressId id)
Definition: isolate.cc:417
static Failure * OutOfMemoryException()
Definition: objects-inl.h:1029
void IterateDeferredHandles(ObjectVisitor *visitor)
Definition: isolate.cc:480
bool(* IndexedSecurityCallback)(Local< Object > host, uint32_t index, AccessType type, Local< Value > data)
Definition: v8.h:2154
void DoThrow(Object *exception, MessageLocation *location)
Definition: isolate.cc:1084
void mark_out_of_memory()
Definition: isolate.h:1446
Bootstrapper * bootstrapper()
Definition: isolate.h:818
static Failure * Exception()
Definition: objects-inl.h:1024
Failure * ReThrow(MaybeObject *exception)
Definition: isolate.cc:951
PerIsolateThreadData * FindPerThreadDataForThisThread()
Definition: isolate.cc:352
struct v8::internal::StaticInitializer static_initializer
virtual void Summarize(List< FrameSummary > *frames)
Definition: frames.cc:741
static Address handler(ThreadLocalTop *thread)
Definition: isolate.h:627
#define ASSERT(condition)
Definition: checks.h:270
static PerIsolateThreadData * CurrentPerIsolateThreadData()
Definition: isolate.h:433
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback)
Definition: isolate.cc:767
static StackGuard * GetDefaultIsolateStackGuard()
Definition: isolate.cc:393
static Script * cast(Object *obj)
void clear_pending_exception()
Definition: isolate.h:555
static Context * cast(Object *context)
Definition: contexts.h:212
#define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)
void clear_scheduled_exception()
Definition: isolate.h:609
static void UnregisterCTryCatch()
Definition: simulator-arm.h:81
void PreallocatedStorageInit(size_t size)
Definition: isolate.cc:245
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:282
Factory * factory()
Definition: isolate.h:992
static int GetThreadLocalInt(LocalStorageKey key)
Definition: platform.h:495
Handle< String > LookupAsciiSymbol(Vector< const char > str)
Definition: factory.cc:174
static Handle< Object > SetHiddenProperty(Handle< JSObject > obj, Handle< String > key, Handle< Object > value)
Definition: objects.cc:3601
Handle< String > ToString()
static Smi * cast(Object *object)
void(* FailedAccessCheckCallback)(Local< Object > target, AccessType type, Local< Value > data)
Definition: v8.h:2727
void clear_pending_message()
Definition: isolate.h:564
void CaptureAndSetCurrentStackTraceFor(Handle< JSObject > error_object)
Definition: isolate.cc:556
StackGuard * stack_guard()
Definition: isolate.h:834
void Add(Vector< const char > format, Vector< FmtElm > elms)
Handle< Context > global_context()
Definition: isolate.cc:1351
bool OptionalRescheduleException(bool is_bottom_call)
Definition: isolate.cc:1272
Object * receiver() const
Definition: frames-inl.h:216
Address try_catch_handler_address()
Definition: isolate.h:572
static void Abort()
static void EnsureDefaultIsolate()
Definition: isolate.cc:363
T * start() const
Definition: utils.h:390
void ReportPendingMessages()
Definition: isolate.cc:1230
#define ISOLATE_INIT_LIST(V)
Definition: isolate.h:320
static JSGlobalProxy * cast(Object *obj)
static Address c_entry_fp(ThreadLocalTop *thread)
Definition: isolate.h:624
#define OFFSET_OF(type, field)
Definition: globals.h:273
v8::TryCatch * try_catch_handler()
Definition: isolate.h:569
static ThreadId Current()
Definition: isolate.h:154
Context * native_context()
Definition: contexts.cc:58
static Failure * cast(MaybeObject *object)
Definition: objects-inl.h:496
void ComputeLocation(MessageLocation *target)
Definition: isolate.cc:1017
static void EnterDefaultIsolate()
Definition: isolate.cc:399
const int kPointerSize
Definition: globals.h:220
MaybeObject * scheduled_exception()
Definition: isolate.h:602
static LocalStorageKey CreateThreadLocalKey()
void PrintCurrentStackTrace(FILE *out)
Definition: isolate.cc:989
void Iterate(ObjectVisitor *v)
Definition: isolate.cc:475
Handle< JSArray > CaptureCurrentStackTrace(int frame_limit, StackTrace::StackTraceOptions options)
Definition: isolate.cc:568
Handle< JSValue > GetScriptWrapper(Handle< Script > script)
Definition: handles.cc:366
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:307
static Handle< Object > SetLocalPropertyIgnoreAttributes(Handle< JSObject > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes)
Definition: objects.cc:2952
const Register pc
int length() const
Definition: utils.h:384
int GetScriptLineNumberSafe(Handle< Script > script, int code_pos)
Definition: handles.cc:517
static Mutex * CreateMutex()
Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
bool has_pending_exception()
Definition: isolate.h:561
AccessType
Definition: v8.h:2131
void * PreallocatedStorageNew(size_t size)
Definition: isolate.cc:257
void SetCaptureStackTraceForUncaughtExceptions(bool capture, int frame_limit, StackTrace::StackTraceOptions options)
Definition: isolate.cc:1318
Handle< JSBuiltinsObject > js_builtins_object()
Definition: isolate.h:656
Failure * Throw(Object *exception, MessageLocation *location=NULL)
Definition: isolate.cc:945
Handle< Script > script() const
Definition: messages.h:77
void Release_Store(volatile Atomic32 *ptr, Atomic32 value)
friend class ThreadId
Definition: isolate.h:1302
activate correct semantics for inheriting readonliness false
Definition: flags.cc:141
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static JSArray * cast(Object *obj)
Context * context()
Definition: isolate.h:520
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:479
Failure * PromoteScheduledException()
Definition: isolate.cc:981
virtual void VisitThread(Isolate *isolate, ThreadLocalTop *top)=0
bool IsOutOfMemoryException() const
Definition: objects-inl.h:1007
static void WriteToFlat(String *source, sinkchar *sink, int from, int to)
Definition: objects.cc:6891
bool is_null() const
Definition: handles.h:87
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C)
Definition: isolate.h:138
void IterateThread(ThreadVisitor *v)
Definition: isolate.cc:429
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:775
static AccessCheckInfo * cast(Object *obj)
String * hidden_symbol()
Definition: heap.h:1184
static void IsolateExitedJS(Isolate *isolate)
static void SetThreadLocal(LocalStorageKey key, void *value)
Handle< String > StackTraceString()
Definition: isolate.cc:510
void set_pending_exception(MaybeObject *exception)
Definition: isolate.h:552
virtual void Signal()=0
static void PrintError(const char *format,...)
bool(* NamedSecurityCallback)(Local< Object > host, Local< Value > key, AccessType type, Local< Value > data)
Definition: v8.h:2144
#define TRACE_ISOLATE(tag)
Definition: isolate.cc:1470
bool MayIndexedAccess(JSObject *receiver, uint32_t index, v8::AccessType type)
Definition: isolate.cc:878
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit 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 SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available 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 MIPS FPU instructions if NULL
static void StrNCpy(Vector< char > dest, const char *src, size_t n)
static void StartPreemption(int every_n_ms)
Definition: v8threads.cc:142
static FixedArray * cast(Object *obj)
void InitializeLoggingAndCounters()
Definition: isolate.cc:1781
void UnregisterTryCatchHandler(v8::TryCatch *that)
Definition: isolate.cc:501
Failure * TerminateExecution()
Definition: isolate.cc:939
char * ArchiveThread(char *to)
Definition: isolate.cc:1379
Object * GetHiddenProperty(String *key)
Definition: objects.cc:3568
Failure * ThrowIllegalOperation()
Definition: isolate.cc:966
virtual void Wait()=0
static ThreadId Invalid()
Definition: isolate.h:157
static Handle< String > GetStackTraceLine(Handle< Object > recv, Handle< JSFunction > fun, Handle< Object > pos, Handle< Object > is_global)
Definition: execution.cc:790
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit 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 SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available 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 MIPS FPU instructions if NULL
Definition: flags.cc:301
void RegisterTryCatchHandler(v8::TryCatch *that)
Definition: isolate.cc:489
bool is_catchable_by_javascript(MaybeObject *exception)
Definition: isolate.h:615
static const int kMaxInliningLevels
Definition: compiler.h:419
int32_t Atomic32
Definition: atomicops.h:57
char * RestoreThread(char *from)
Definition: isolate.cc:1393
static void ClearMentionedObjectCache()
bool has_scheduled_exception()
Definition: isolate.h:606
Handle< Context > native_context()
Definition: isolate.cc:1345
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:103
bool ShouldReportException(bool *can_be_caught_externally, bool catchable_by_javascript)
Definition: isolate.cc:1035
T Min(T a, T b)
Definition: utils.h:229
ThreadLocalTop * thread_local_top()
Definition: isolate.h:839
static void StopPreemption()
Definition: v8threads.cc:147
static const char *const kStackOverflowMessage
Definition: isolate.h:785
static void SetThreadLocalInt(LocalStorageKey key, int value)
Definition: platform.h:499
static JSObject * cast(Object *obj)
#define ISOLATE_INIT_ARRAY_LIST(V)
Definition: isolate.h:309
void PreallocatedStorageDelete(void *p)
Definition: isolate.cc:300
#define TRY_CATCH_FROM_ADDRESS(try_catch_address)
Definition: simulator-arm.h:63
Handle< JSObject > Copy(Handle< JSObject > obj)
Definition: handles.cc:335
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset flag
Definition: objects-inl.h:3923
#define ASSIGN_ELEMENT(CamelName, hacker_name)
static JSFunction * cast(Object *obj)