v8  3.11.10(node0.8.26)
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 
482  // The ARM simulator has a separate JS stack. We therefore register
483  // the C++ try catch handler with the simulator and get back an
484  // address that can be used for comparisons with addresses into the
485  // JS stack. When running without the simulator, the address
486  // returned will be the address of the C++ try catch handler itself.
487  Address address = reinterpret_cast<Address>(
488  SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
489  thread_local_top()->set_try_catch_handler_address(address);
490 }
491 
492 
494  ASSERT(thread_local_top()->TryCatchHandler() == that);
495  thread_local_top()->set_try_catch_handler_address(
496  reinterpret_cast<Address>(that->next_));
497  thread_local_top()->catcher_ = NULL;
499 }
500 
501 
503  if (stack_trace_nesting_level_ == 0) {
504  stack_trace_nesting_level_++;
505  HeapStringAllocator allocator;
507  StringStream accumulator(&allocator);
508  incomplete_message_ = &accumulator;
509  PrintStack(&accumulator);
510  Handle<String> stack_trace = accumulator.ToString();
511  incomplete_message_ = NULL;
512  stack_trace_nesting_level_ = 0;
513  return stack_trace;
514  } else if (stack_trace_nesting_level_ == 1) {
515  stack_trace_nesting_level_++;
517  "\n\nAttempt to print stack while printing stack (double fault)\n");
519  "If you are lucky you may find a partial stack dump on stdout.\n\n");
520  incomplete_message_->OutputToStdOut();
521  return factory()->empty_symbol();
522  } else {
523  OS::Abort();
524  // Unreachable
525  return factory()->empty_symbol();
526  }
527 }
528 
529 
531  if (capture_stack_trace_for_uncaught_exceptions_) {
532  // Capture stack trace for a detailed exception message.
533  Handle<String> key = factory()->hidden_stack_trace_symbol();
535  stack_trace_for_uncaught_exceptions_frame_limit_,
536  stack_trace_for_uncaught_exceptions_options_);
537  JSObject::SetHiddenProperty(error_object, key, stack_trace);
538  }
539 }
540 
541 
543  int frame_limit, StackTrace::StackTraceOptions options) {
544  // Ensure no negative values.
545  int limit = Max(frame_limit, 0);
546  Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
547 
548  Handle<String> column_key = factory()->LookupAsciiSymbol("column");
549  Handle<String> line_key = factory()->LookupAsciiSymbol("lineNumber");
550  Handle<String> script_key = factory()->LookupAsciiSymbol("scriptName");
551  Handle<String> name_or_source_url_key =
552  factory()->LookupAsciiSymbol("nameOrSourceURL");
553  Handle<String> script_name_or_source_url_key =
554  factory()->LookupAsciiSymbol("scriptNameOrSourceURL");
555  Handle<String> function_key = factory()->LookupAsciiSymbol("functionName");
556  Handle<String> eval_key = factory()->LookupAsciiSymbol("isEval");
557  Handle<String> constructor_key =
558  factory()->LookupAsciiSymbol("isConstructor");
559 
560  StackTraceFrameIterator it(this);
561  int frames_seen = 0;
562  while (!it.done() && (frames_seen < limit)) {
563  JavaScriptFrame* frame = it.frame();
564  // Set initial size to the maximum inlining level + 1 for the outermost
565  // function.
567  frame->Summarize(&frames);
568  for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
569  // Create a JSObject to hold the information for the StackFrame.
570  Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
571 
572  Handle<JSFunction> fun = frames[i].function();
573  Handle<Script> script(Script::cast(fun->shared()->script()));
574 
575  if (options & StackTrace::kLineNumber) {
576  int script_line_offset = script->line_offset()->value();
577  int position = frames[i].code()->SourcePosition(frames[i].pc());
578  int line_number = GetScriptLineNumber(script, position);
579  // line_number is already shifted by the script_line_offset.
580  int relative_line_number = line_number - script_line_offset;
581  if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
582  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
583  int start = (relative_line_number == 0) ? 0 :
584  Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
585  int column_offset = position - start;
586  if (relative_line_number == 0) {
587  // For the case where the code is on the same line as the script
588  // tag.
589  column_offset += script->column_offset()->value();
590  }
592  this,
594  stack_frame, column_key,
595  Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE));
596  }
598  this,
600  stack_frame, line_key,
601  Handle<Smi>(Smi::FromInt(line_number + 1)), NONE));
602  }
603 
604  if (options & StackTrace::kScriptName) {
605  Handle<Object> script_name(script->name(), this);
608  stack_frame, script_key, script_name, NONE));
609  }
610 
611  if (options & StackTrace::kScriptNameOrSourceURL) {
612  Handle<Object> script_name(script->name(), this);
613  Handle<JSValue> script_wrapper = GetScriptWrapper(script);
614  Handle<Object> property = GetProperty(script_wrapper,
615  name_or_source_url_key);
616  ASSERT(property->IsJSFunction());
617  Handle<JSFunction> method = Handle<JSFunction>::cast(property);
618  bool caught_exception;
619  Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
620  NULL, &caught_exception);
621  if (caught_exception) {
622  result = factory()->undefined_value();
623  }
626  stack_frame, script_name_or_source_url_key,
627  result, NONE));
628  }
629 
630  if (options & StackTrace::kFunctionName) {
631  Handle<Object> fun_name(fun->shared()->name(), this);
632  if (fun_name->ToBoolean()->IsFalse()) {
633  fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
634  }
637  stack_frame, function_key, fun_name, NONE));
638  }
639 
640  if (options & StackTrace::kIsEval) {
641  int type = Smi::cast(script->compilation_type())->value();
642  Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
643  factory()->true_value() : factory()->false_value();
646  stack_frame, eval_key, is_eval, NONE));
647  }
648 
649  if (options & StackTrace::kIsConstructor) {
650  Handle<Object> is_constructor = (frames[i].is_constructor()) ?
651  factory()->true_value() : factory()->false_value();
654  stack_frame, constructor_key,
655  is_constructor, NONE));
656  }
657 
658  FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
659  frames_seen++;
660  }
661  it.Advance();
662  }
663 
664  stack_trace->set_length(Smi::FromInt(frames_seen));
665  return stack_trace;
666 }
667 
668 
670  if (stack_trace_nesting_level_ == 0) {
671  stack_trace_nesting_level_++;
672 
673  StringAllocator* allocator;
674  if (preallocated_message_space_ == NULL) {
675  allocator = new HeapStringAllocator();
676  } else {
677  allocator = preallocated_message_space_;
678  }
679 
681  StringStream accumulator(allocator);
682  incomplete_message_ = &accumulator;
683  PrintStack(&accumulator);
684  accumulator.OutputToStdOut();
686  accumulator.Log();
687  incomplete_message_ = NULL;
688  stack_trace_nesting_level_ = 0;
689  if (preallocated_message_space_ == NULL) {
690  // Remove the HeapStringAllocator created above.
691  delete allocator;
692  }
693  } else if (stack_trace_nesting_level_ == 1) {
694  stack_trace_nesting_level_++;
696  "\n\nAttempt to print stack while printing stack (double fault)\n");
698  "If you are lucky you may find a partial stack dump on stdout.\n\n");
699  incomplete_message_->OutputToStdOut();
700  }
701 }
702 
703 
704 static void PrintFrames(StringStream* accumulator,
705  StackFrame::PrintMode mode) {
706  StackFrameIterator it;
707  for (int i = 0; !it.done(); it.Advance()) {
708  it.frame()->Print(accumulator, mode, i++);
709  }
710 }
711 
712 
713 void Isolate::PrintStack(StringStream* accumulator) {
714  if (!IsInitialized()) {
715  accumulator->Add(
716  "\n==== Stack trace is not available ==========================\n\n");
717  accumulator->Add(
718  "\n==== Isolate for the thread is not initialized =============\n\n");
719  return;
720  }
721  // The MentionedObjectCache is not GC-proof at the moment.
722  AssertNoAllocation nogc;
723  ASSERT(StringStream::IsMentionedObjectCacheClear());
724 
725  // Avoid printing anything if there are no frames.
726  if (c_entry_fp(thread_local_top()) == 0) return;
727 
728  accumulator->Add(
729  "\n==== Stack trace ============================================\n\n");
730  PrintFrames(accumulator, StackFrame::OVERVIEW);
731 
732  accumulator->Add(
733  "\n==== Details ================================================\n\n");
734  PrintFrames(accumulator, StackFrame::DETAILS);
735 
736  accumulator->PrintMentionedObjectCache();
737  accumulator->Add("=====================\n\n");
738 }
739 
740 
743  thread_local_top()->failed_access_check_callback_ = callback;
744 }
745 
746 
748  if (!thread_local_top()->failed_access_check_callback_) return;
749 
750  ASSERT(receiver->IsAccessCheckNeeded());
751  ASSERT(context());
752 
753  // Get the data object from access check info.
754  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
755  if (!constructor->shared()->IsApiFunction()) return;
756  Object* data_obj =
757  constructor->shared()->get_api_func_data()->access_check_info();
758  if (data_obj == heap_.undefined_value()) return;
759 
760  HandleScope scope;
761  Handle<JSObject> receiver_handle(receiver);
762  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
763  { VMState state(this, EXTERNAL);
764  thread_local_top()->failed_access_check_callback_(
765  v8::Utils::ToLocal(receiver_handle),
766  type,
767  v8::Utils::ToLocal(data));
768  }
769 }
770 
771 
774 };
775 
776 
777 static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
778  JSObject* receiver,
780  // During bootstrapping, callback functions are not enabled yet.
781  if (isolate->bootstrapper()->IsActive()) return YES;
782 
783  if (receiver->IsJSGlobalProxy()) {
784  Object* receiver_context = JSGlobalProxy::cast(receiver)->context();
785  if (!receiver_context->IsContext()) return NO;
786 
787  // Get the global context of current top context.
788  // avoid using Isolate::global_context() because it uses Handle.
789  Context* global_context = isolate->context()->global()->global_context();
790  if (receiver_context == global_context) return YES;
791 
792  if (Context::cast(receiver_context)->security_token() ==
793  global_context->security_token())
794  return YES;
795  }
796 
797  return UNKNOWN;
798 }
799 
800 
803  ASSERT(receiver->IsAccessCheckNeeded());
804 
805  // The callers of this method are not expecting a GC.
806  AssertNoAllocation no_gc;
807 
808  // Skip checks for hidden properties access. Note, we do not
809  // require existence of a context in this case.
810  if (key == heap_.hidden_symbol()) return true;
811 
812  // Check for compatibility between the security tokens in the
813  // current lexical context and the accessed object.
814  ASSERT(context());
815 
816  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
817  if (decision != UNKNOWN) return decision == YES;
818 
819  // Get named access check callback
820  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
821  if (!constructor->shared()->IsApiFunction()) return false;
822 
823  Object* data_obj =
824  constructor->shared()->get_api_func_data()->access_check_info();
825  if (data_obj == heap_.undefined_value()) return false;
826 
827  Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
828  v8::NamedSecurityCallback callback =
829  v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
830 
831  if (!callback) return false;
832 
833  HandleScope scope(this);
834  Handle<JSObject> receiver_handle(receiver, this);
835  Handle<Object> key_handle(key, this);
836  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
837  LOG(this, ApiNamedSecurityCheck(key));
838  bool result = false;
839  {
840  // Leaving JavaScript.
841  VMState state(this, EXTERNAL);
842  result = callback(v8::Utils::ToLocal(receiver_handle),
843  v8::Utils::ToLocal(key_handle),
844  type,
845  v8::Utils::ToLocal(data));
846  }
847  return result;
848 }
849 
850 
852  uint32_t index,
854  ASSERT(receiver->IsAccessCheckNeeded());
855  // Check for compatibility between the security tokens in the
856  // current lexical context and the accessed object.
857  ASSERT(context());
858 
859  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
860  if (decision != UNKNOWN) return decision == YES;
861 
862  // Get indexed access check callback
863  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
864  if (!constructor->shared()->IsApiFunction()) return false;
865 
866  Object* data_obj =
867  constructor->shared()->get_api_func_data()->access_check_info();
868  if (data_obj == heap_.undefined_value()) return false;
869 
870  Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
871  v8::IndexedSecurityCallback callback =
872  v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
873 
874  if (!callback) return false;
875 
876  HandleScope scope(this);
877  Handle<JSObject> receiver_handle(receiver, this);
878  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
879  LOG(this, ApiIndexedSecurityCheck(index));
880  bool result = false;
881  {
882  // Leaving JavaScript.
883  VMState state(this, EXTERNAL);
884  result = callback(v8::Utils::ToLocal(receiver_handle),
885  index,
886  type,
887  v8::Utils::ToLocal(data));
888  }
889  return result;
890 }
891 
892 
893 const char* const Isolate::kStackOverflowMessage =
894  "Uncaught RangeError: Maximum call stack size exceeded";
895 
896 
898  HandleScope scope;
899  Handle<String> key = factory()->stack_overflow_symbol();
900  Handle<JSObject> boilerplate =
902  Handle<Object> exception = Copy(boilerplate);
903  // TODO(1240995): To avoid having to call JavaScript code to compute
904  // the message for stack overflow exceptions which is very likely to
905  // double fault with another stack overflow exception, we use a
906  // precomputed message.
907  DoThrow(*exception, NULL);
908  return Failure::Exception();
909 }
910 
911 
913  DoThrow(heap_.termination_exception(), NULL);
914  return Failure::Exception();
915 }
916 
917 
918 Failure* Isolate::Throw(Object* exception, MessageLocation* location) {
919  DoThrow(exception, location);
920  return Failure::Exception();
921 }
922 
923 
924 Failure* Isolate::ReThrow(MaybeObject* exception) {
925  bool can_be_caught_externally = false;
926  bool catchable_by_javascript = is_catchable_by_javascript(exception);
927  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
928 
929  thread_local_top()->catcher_ = can_be_caught_externally ?
931 
932  // Set the exception being re-thrown.
933  set_pending_exception(exception);
934  if (exception->IsFailure()) return exception->ToFailureUnchecked();
935  return Failure::Exception();
936 }
937 
938 
940  return Throw(heap_.illegal_access_symbol());
941 }
942 
943 
944 void Isolate::ScheduleThrow(Object* exception) {
945  // When scheduling a throw we first throw the exception to get the
946  // error reporting if it is uncaught before rescheduling it.
947  Throw(exception);
948  thread_local_top()->scheduled_exception_ = pending_exception();
949  thread_local_top()->external_caught_exception_ = false;
951 }
952 
953 
955  MaybeObject* thrown = scheduled_exception();
957  // Re-throw the exception to avoid getting repeated error reporting.
958  return ReThrow(thrown);
959 }
960 
961 
963  StackTraceFrameIterator it(this);
964  while (!it.done()) {
965  HandleScope scope;
966  // Find code position if recorded in relocation info.
967  JavaScriptFrame* frame = it.frame();
968  int pos = frame->LookupCode()->SourcePosition(frame->pc());
969  Handle<Object> pos_obj(Smi::FromInt(pos));
970  // Fetch function and receiver.
972  Handle<Object> recv(frame->receiver());
973  // Advance to the next JavaScript frame and determine if the
974  // current frame is the top-level frame.
975  it.Advance();
976  Handle<Object> is_top_level = it.done()
977  ? factory()->true_value()
978  : factory()->false_value();
979  // Generate and print stack trace line.
980  Handle<String> line =
981  Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
982  if (line->length() > 0) {
983  line->PrintOn(out);
984  fprintf(out, "\n");
985  }
986  }
987 }
988 
989 
991  *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
992  StackTraceFrameIterator it(this);
993  if (!it.done()) {
994  JavaScriptFrame* frame = it.frame();
995  JSFunction* fun = JSFunction::cast(frame->function());
996  Object* script = fun->shared()->script();
997  if (script->IsScript() &&
998  !(Script::cast(script)->source()->IsUndefined())) {
999  int pos = frame->LookupCode()->SourcePosition(frame->pc());
1000  // Compute the location from the function and the reloc info.
1001  Handle<Script> casted_script(Script::cast(script));
1002  *target = MessageLocation(casted_script, pos, pos + 1);
1003  }
1004  }
1005 }
1006 
1007 
1008 bool Isolate::ShouldReportException(bool* can_be_caught_externally,
1009  bool catchable_by_javascript) {
1010  // Find the top-most try-catch handler.
1011  StackHandler* handler =
1012  StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1013  while (handler != NULL && !handler->is_catch()) {
1014  handler = handler->next();
1015  }
1016 
1017  // Get the address of the external handler so we can compare the address to
1018  // determine which one is closer to the top of the stack.
1019  Address external_handler_address =
1020  thread_local_top()->try_catch_handler_address();
1021 
1022  // The exception has been externally caught if and only if there is
1023  // an external handler which is on top of the top-most try-catch
1024  // handler.
1025  *can_be_caught_externally = external_handler_address != NULL &&
1026  (handler == NULL || handler->address() > external_handler_address ||
1027  !catchable_by_javascript);
1028 
1029  if (*can_be_caught_externally) {
1030  // Only report the exception if the external handler is verbose.
1031  return try_catch_handler()->is_verbose_;
1032  } else {
1033  // Report the exception if it isn't caught by JavaScript code.
1034  return handler == NULL;
1035  }
1036 }
1037 
1038 
1039 bool Isolate::IsErrorObject(Handle<Object> obj) {
1040  if (!obj->IsJSObject()) return false;
1041 
1042  String* error_key = *(factory()->LookupAsciiSymbol("$Error"));
1043  Object* error_constructor =
1044  js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
1045 
1046  for (Object* prototype = *obj; !prototype->IsNull();
1047  prototype = prototype->GetPrototype()) {
1048  if (!prototype->IsJSObject()) return false;
1049  if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
1050  return true;
1051  }
1052  }
1053  return false;
1054 }
1055 
1056 
1057 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
1059 
1060  HandleScope scope;
1061  Handle<Object> exception_handle(exception);
1062 
1063  // Determine reporting and whether the exception is caught externally.
1064  bool catchable_by_javascript = is_catchable_by_javascript(exception);
1065  bool can_be_caught_externally = false;
1066  bool should_report_exception =
1067  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
1068  bool report_exception = catchable_by_javascript && should_report_exception;
1069  bool try_catch_needs_message =
1070  can_be_caught_externally && try_catch_handler()->capture_message_;
1071  bool bootstrapping = bootstrapper()->IsActive();
1072 
1073 #ifdef ENABLE_DEBUGGER_SUPPORT
1074  // Notify debugger of exception.
1075  if (catchable_by_javascript) {
1076  debugger_->OnException(exception_handle, report_exception);
1077  }
1078 #endif
1079 
1080  // Generate the message if required.
1081  if (report_exception || try_catch_needs_message) {
1082  MessageLocation potential_computed_location;
1083  if (location == NULL) {
1084  // If no location was specified we use a computed one instead.
1085  ComputeLocation(&potential_computed_location);
1086  location = &potential_computed_location;
1087  }
1088  // It's not safe to try to make message objects or collect stack traces
1089  // while the bootstrapper is active since the infrastructure may not have
1090  // been properly initialized.
1091  if (!bootstrapping) {
1092  Handle<String> stack_trace;
1093  if (FLAG_trace_exception) stack_trace = StackTraceString();
1094  Handle<JSArray> stack_trace_object;
1095  if (capture_stack_trace_for_uncaught_exceptions_) {
1096  if (IsErrorObject(exception_handle)) {
1097  // We fetch the stack trace that corresponds to this error object.
1098  String* key = heap()->hidden_stack_trace_symbol();
1099  Object* stack_property =
1100  JSObject::cast(*exception_handle)->GetHiddenProperty(key);
1101  // Property lookup may have failed. In this case it's probably not
1102  // a valid Error object.
1103  if (stack_property->IsJSArray()) {
1104  stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
1105  }
1106  }
1107  if (stack_trace_object.is_null()) {
1108  // Not an error object, we capture at throw site.
1109  stack_trace_object = CaptureCurrentStackTrace(
1110  stack_trace_for_uncaught_exceptions_frame_limit_,
1111  stack_trace_for_uncaught_exceptions_options_);
1112  }
1113  }
1115  "uncaught_exception",
1116  location,
1117  HandleVector<Object>(&exception_handle, 1),
1118  stack_trace,
1119  stack_trace_object);
1120  thread_local_top()->pending_message_obj_ = *message_obj;
1121  if (location != NULL) {
1122  thread_local_top()->pending_message_script_ = *location->script();
1123  thread_local_top()->pending_message_start_pos_ = location->start_pos();
1124  thread_local_top()->pending_message_end_pos_ = location->end_pos();
1125  }
1126  } else if (location != NULL && !location->script().is_null()) {
1127  // We are bootstrapping and caught an error where the location is set
1128  // and we have a script for the location.
1129  // In this case we could have an extension (or an internal error
1130  // somewhere) and we print out the line number at which the error occured
1131  // to the console for easier debugging.
1132  int line_number = GetScriptLineNumberSafe(location->script(),
1133  location->start_pos());
1134  if (exception->IsString()) {
1136  "Extension or internal compilation error: %s in %s at line %d.\n",
1137  *String::cast(exception)->ToCString(),
1138  *String::cast(location->script()->name())->ToCString(),
1139  line_number);
1140  } else {
1142  "Extension or internal compilation error in %s at line %d.\n",
1143  *String::cast(location->script()->name())->ToCString(),
1144  line_number);
1145  }
1146  }
1147  }
1148 
1149  // Save the message for reporting if the the exception remains uncaught.
1150  thread_local_top()->has_pending_message_ = report_exception;
1151 
1152  // Do not forget to clean catcher_ if currently thrown exception cannot
1153  // be caught. If necessary, ReThrow will update the catcher.
1154  thread_local_top()->catcher_ = can_be_caught_externally ?
1155  try_catch_handler() : NULL;
1156 
1157  set_pending_exception(*exception_handle);
1158 }
1159 
1160 
1163 
1164  if ((thread_local_top()->catcher_ == NULL) ||
1165  (try_catch_handler() != thread_local_top()->catcher_)) {
1166  // When throwing the exception, we found no v8::TryCatch
1167  // which should care about this exception.
1168  return false;
1169  }
1170 
1172  return true;
1173  }
1174 
1175  // Get the address of the external handler so we can compare the address to
1176  // determine which one is closer to the top of the stack.
1177  Address external_handler_address =
1178  thread_local_top()->try_catch_handler_address();
1179  ASSERT(external_handler_address != NULL);
1180 
1181  // The exception has been externally caught if and only if there is
1182  // an external handler which is on top of the top-most try-finally
1183  // handler.
1184  // There should be no try-catch blocks as they would prohibit us from
1185  // finding external catcher in the first place (see catcher_ check above).
1186  //
1187  // Note, that finally clause would rethrow an exception unless it's
1188  // aborted by jumps in control flow like return, break, etc. and we'll
1189  // have another chances to set proper v8::TryCatch.
1190  StackHandler* handler =
1191  StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1192  while (handler != NULL && handler->address() < external_handler_address) {
1193  ASSERT(!handler->is_catch());
1194  if (handler->is_finally()) return false;
1195 
1196  handler = handler->next();
1197  }
1198 
1199  return true;
1200 }
1201 
1202 
1205  PropagatePendingExceptionToExternalTryCatch();
1206 
1207  // If the pending exception is OutOfMemoryException set out_of_memory in
1208  // the global context. Note: We have to mark the global context here
1209  // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
1210  // set it.
1211  HandleScope scope;
1212  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
1214  } else if (thread_local_top_.pending_exception_ ==
1215  heap()->termination_exception()) {
1216  // Do nothing: if needed, the exception has been already propagated to
1217  // v8::TryCatch.
1218  } else {
1219  if (thread_local_top_.has_pending_message_) {
1220  thread_local_top_.has_pending_message_ = false;
1221  if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
1222  HandleScope scope;
1223  Handle<Object> message_obj(thread_local_top_.pending_message_obj_);
1224  if (thread_local_top_.pending_message_script_ != NULL) {
1225  Handle<Script> script(thread_local_top_.pending_message_script_);
1226  int start_pos = thread_local_top_.pending_message_start_pos_;
1227  int end_pos = thread_local_top_.pending_message_end_pos_;
1228  MessageLocation location(script, start_pos, end_pos);
1229  MessageHandler::ReportMessage(this, &location, message_obj);
1230  } else {
1231  MessageHandler::ReportMessage(this, NULL, message_obj);
1232  }
1233  }
1234  }
1235  }
1237 }
1238 
1239 
1241  FLAG_trace_exception = flag; // TODO(isolates): This is an unfortunate use.
1242 }
1243 
1244 
1245 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
1247  PropagatePendingExceptionToExternalTryCatch();
1248 
1249  // Always reschedule out of memory exceptions.
1250  if (!is_out_of_memory()) {
1251  bool is_termination_exception =
1252  pending_exception() == heap_.termination_exception();
1253 
1254  // Do not reschedule the exception if this is the bottom call.
1255  bool clear_exception = is_bottom_call;
1256 
1257  if (is_termination_exception) {
1258  if (is_bottom_call) {
1259  thread_local_top()->external_caught_exception_ = false;
1261  return false;
1262  }
1263  } else if (thread_local_top()->external_caught_exception_) {
1264  // If the exception is externally caught, clear it if there are no
1265  // JavaScript frames on the way to the C++ frame that has the
1266  // external handler.
1268  Address external_handler_address =
1269  thread_local_top()->try_catch_handler_address();
1271  if (it.done() || (it.frame()->sp() > external_handler_address)) {
1272  clear_exception = true;
1273  }
1274  }
1275 
1276  // Clear the exception if needed.
1277  if (clear_exception) {
1278  thread_local_top()->external_caught_exception_ = false;
1280  return false;
1281  }
1282  }
1283 
1284  // Reschedule the exception.
1285  thread_local_top()->scheduled_exception_ = pending_exception();
1287  return true;
1288 }
1289 
1290 
1292  bool capture,
1293  int frame_limit,
1295  capture_stack_trace_for_uncaught_exceptions_ = capture;
1296  stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
1297  stack_trace_for_uncaught_exceptions_options_ = options;
1298 }
1299 
1300 
1302  if (has_pending_exception()) {
1303  MaybeObject* e = pending_exception();
1304  if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1305  return true;
1306  }
1307  }
1308  if (has_scheduled_exception()) {
1309  MaybeObject* e = scheduled_exception();
1310  if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1311  return true;
1312  }
1313  }
1314  return false;
1315 }
1316 
1317 
1319  GlobalObject* global = thread_local_top()->context_->global();
1320  return Handle<Context>(global->global_context());
1321 }
1322 
1323 
1326 #ifdef ENABLE_DEBUGGER_SUPPORT
1327  if (debug_->InDebugger()) {
1328  while (!it.done()) {
1329  JavaScriptFrame* frame = it.frame();
1330  Context* context = Context::cast(frame->context());
1331  if (context->global_context() == *debug_->debug_context()) {
1332  it.Advance();
1333  } else {
1334  break;
1335  }
1336  }
1337  }
1338 #endif // ENABLE_DEBUGGER_SUPPORT
1339  if (it.done()) return Handle<Context>::null();
1340  JavaScriptFrame* frame = it.frame();
1341  Context* context = Context::cast(frame->context());
1342  return Handle<Context>(context->global_context());
1343 }
1344 
1345 
1346 char* Isolate::ArchiveThread(char* to) {
1347  if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
1349  }
1350  memcpy(to, reinterpret_cast<char*>(thread_local_top()),
1351  sizeof(ThreadLocalTop));
1352  InitializeThreadLocal();
1356  return to + sizeof(ThreadLocalTop);
1357 }
1358 
1359 
1360 char* Isolate::RestoreThread(char* from) {
1361  memcpy(reinterpret_cast<char*>(thread_local_top()), from,
1362  sizeof(ThreadLocalTop));
1363  // This might be just paranoia, but it seems to be needed in case a
1364  // thread_local_top_ is restored on a separate OS thread.
1365 #ifdef USE_SIMULATOR
1366 #ifdef V8_TARGET_ARCH_ARM
1367  thread_local_top()->simulator_ = Simulator::current(this);
1368 #elif V8_TARGET_ARCH_MIPS
1369  thread_local_top()->simulator_ = Simulator::current(this);
1370 #endif
1371 #endif
1372  if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
1374  }
1375  ASSERT(context() == NULL || context()->IsContext());
1376  return from + sizeof(ThreadLocalTop);
1377 }
1378 
1379 
1380 Isolate::ThreadDataTable::ThreadDataTable()
1381  : list_(NULL) {
1382 }
1383 
1384 
1385 Isolate::PerIsolateThreadData*
1386  Isolate::ThreadDataTable::Lookup(Isolate* isolate,
1387  ThreadId thread_id) {
1388  for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
1389  if (data->Matches(isolate, thread_id)) return data;
1390  }
1391  return NULL;
1392 }
1393 
1394 
1395 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
1396  if (list_ != NULL) list_->prev_ = data;
1397  data->next_ = list_;
1398  list_ = data;
1399 }
1400 
1401 
1402 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
1403  if (list_ == data) list_ = data->next_;
1404  if (data->next_ != NULL) data->next_->prev_ = data->prev_;
1405  if (data->prev_ != NULL) data->prev_->next_ = data->next_;
1406  delete data;
1407 }
1408 
1409 
1410 void Isolate::ThreadDataTable::Remove(Isolate* isolate,
1411  ThreadId thread_id) {
1412  PerIsolateThreadData* data = Lookup(isolate, thread_id);
1413  if (data != NULL) {
1414  Remove(data);
1415  }
1416 }
1417 
1418 
1419 void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
1420  PerIsolateThreadData* data = list_;
1421  while (data != NULL) {
1422  PerIsolateThreadData* next = data->next_;
1423  if (data->isolate() == isolate) Remove(data);
1424  data = next;
1425  }
1426 }
1427 
1428 
1429 #ifdef DEBUG
1430 #define TRACE_ISOLATE(tag) \
1431  do { \
1432  if (FLAG_trace_isolates) { \
1433  PrintF("Isolate %p " #tag "\n", reinterpret_cast<void*>(this)); \
1434  } \
1435  } while (false)
1436 #else
1437 #define TRACE_ISOLATE(tag)
1438 #endif
1439 
1440 
1441 Isolate::Isolate()
1442  : state_(UNINITIALIZED),
1443  embedder_data_(NULL),
1444  entry_stack_(NULL),
1445  stack_trace_nesting_level_(0),
1446  incomplete_message_(NULL),
1447  preallocated_memory_thread_(NULL),
1448  preallocated_message_space_(NULL),
1449  bootstrapper_(NULL),
1450  runtime_profiler_(NULL),
1451  compilation_cache_(NULL),
1452  counters_(NULL),
1453  code_range_(NULL),
1454  // Must be initialized early to allow v8::SetResourceConstraints calls.
1455  break_access_(OS::CreateMutex()),
1456  debugger_initialized_(false),
1457  // Must be initialized early to allow v8::Debug calls.
1458  debugger_access_(OS::CreateMutex()),
1459  logger_(NULL),
1460  stats_table_(NULL),
1461  stub_cache_(NULL),
1462  deoptimizer_data_(NULL),
1463  capture_stack_trace_for_uncaught_exceptions_(false),
1464  stack_trace_for_uncaught_exceptions_frame_limit_(0),
1465  stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
1466  transcendental_cache_(NULL),
1467  memory_allocator_(NULL),
1468  keyed_lookup_cache_(NULL),
1469  context_slot_cache_(NULL),
1470  descriptor_lookup_cache_(NULL),
1471  handle_scope_implementer_(NULL),
1472  unicode_cache_(NULL),
1473  in_use_list_(0),
1474  free_list_(0),
1475  preallocated_storage_preallocated_(false),
1476  inner_pointer_to_code_cache_(NULL),
1477  write_input_buffer_(NULL),
1478  global_handles_(NULL),
1479  context_switcher_(NULL),
1480  thread_manager_(NULL),
1481  fp_stubs_generated_(false),
1482  has_installed_extensions_(false),
1483  string_tracker_(NULL),
1484  regexp_stack_(NULL),
1485  date_cache_(NULL),
1486  context_exit_happened_(false) {
1487  TRACE_ISOLATE(constructor);
1488 
1489  memset(isolate_addresses_, 0,
1490  sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
1491 
1492  heap_.isolate_ = this;
1493  zone_.isolate_ = this;
1494  stack_guard_.isolate_ = this;
1495 
1496  // ThreadManager is initialized early to support locking an isolate
1497  // before it is entered.
1498  thread_manager_ = new ThreadManager();
1499  thread_manager_->isolate_ = this;
1500 
1501 #if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
1502  defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
1503  simulator_initialized_ = false;
1504  simulator_i_cache_ = NULL;
1505  simulator_redirection_ = NULL;
1506 #endif
1507 
1508 #ifdef DEBUG
1509  // heap_histograms_ initializes itself.
1510  memset(&js_spill_information_, 0, sizeof(js_spill_information_));
1511  memset(code_kind_statistics_, 0,
1512  sizeof(code_kind_statistics_[0]) * Code::NUMBER_OF_KINDS);
1513 #endif
1514 
1515 #ifdef ENABLE_DEBUGGER_SUPPORT
1516  debug_ = NULL;
1517  debugger_ = NULL;
1518 #endif
1519 
1520  handle_scope_data_.Initialize();
1521 
1522 #define ISOLATE_INIT_EXECUTE(type, name, initial_value) \
1523  name##_ = (initial_value);
1525 #undef ISOLATE_INIT_EXECUTE
1526 
1527 #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length) \
1528  memset(name##_, 0, sizeof(type) * length);
1530 #undef ISOLATE_INIT_ARRAY_EXECUTE
1531 }
1532 
1533 void Isolate::TearDown() {
1534  TRACE_ISOLATE(tear_down);
1535 
1536  // Temporarily set this isolate as current so that various parts of
1537  // the isolate can access it in their destructors without having a
1538  // direct pointer. We don't use Enter/Exit here to avoid
1539  // initializing the thread data.
1540  PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
1541  Isolate* saved_isolate = UncheckedCurrent();
1542  SetIsolateThreadLocals(this, NULL);
1543 
1544  Deinit();
1545 
1546  { ScopedLock lock(process_wide_mutex_);
1547  thread_data_table_->RemoveAllThreads(this);
1548  }
1549 
1550  if (!IsDefaultIsolate()) {
1551  delete this;
1552  }
1553 
1554  // Restore the previous current isolate.
1555  SetIsolateThreadLocals(saved_isolate, saved_data);
1556 }
1557 
1558 
1559 void Isolate::Deinit() {
1560  if (state_ == INITIALIZED) {
1561  TRACE_ISOLATE(deinit);
1562 
1563  if (FLAG_hydrogen_stats) HStatistics::Instance()->Print();
1564 
1565  // We must stop the logger before we tear down other components.
1566  logger_->EnsureTickerStopped();
1567 
1568  delete deoptimizer_data_;
1569  deoptimizer_data_ = NULL;
1570  if (FLAG_preemption) {
1571  v8::Locker locker;
1573  }
1574  builtins_.TearDown();
1575  bootstrapper_->TearDown();
1576 
1577  // Remove the external reference to the preallocated stack memory.
1578  delete preallocated_message_space_;
1579  preallocated_message_space_ = NULL;
1580  PreallocatedMemoryThreadStop();
1581 
1582  HeapProfiler::TearDown();
1583  CpuProfiler::TearDown();
1584  if (runtime_profiler_ != NULL) {
1585  runtime_profiler_->TearDown();
1586  delete runtime_profiler_;
1587  runtime_profiler_ = NULL;
1588  }
1589  heap_.TearDown();
1590  logger_->TearDown();
1591 
1592  // The default isolate is re-initializable due to legacy API.
1593  state_ = UNINITIALIZED;
1594  }
1595 }
1596 
1597 
1598 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
1599  PerIsolateThreadData* data) {
1600  Thread::SetThreadLocal(isolate_key_, isolate);
1601  Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
1602 }
1603 
1604 
1605 Isolate::~Isolate() {
1606  TRACE_ISOLATE(destructor);
1607 
1608  // Has to be called while counters_ are still alive.
1609  zone_.DeleteKeptSegment();
1610 
1611  delete[] assembler_spare_buffer_;
1612  assembler_spare_buffer_ = NULL;
1613 
1614  delete unicode_cache_;
1615  unicode_cache_ = NULL;
1616 
1617  delete date_cache_;
1618  date_cache_ = NULL;
1619 
1620  delete regexp_stack_;
1621  regexp_stack_ = NULL;
1622 
1623  delete descriptor_lookup_cache_;
1624  descriptor_lookup_cache_ = NULL;
1625  delete context_slot_cache_;
1626  context_slot_cache_ = NULL;
1627  delete keyed_lookup_cache_;
1628  keyed_lookup_cache_ = NULL;
1629 
1630  delete transcendental_cache_;
1631  transcendental_cache_ = NULL;
1632  delete stub_cache_;
1633  stub_cache_ = NULL;
1634  delete stats_table_;
1635  stats_table_ = NULL;
1636 
1637  delete logger_;
1638  logger_ = NULL;
1639 
1640  delete counters_;
1641  counters_ = NULL;
1642 
1643  delete handle_scope_implementer_;
1644  handle_scope_implementer_ = NULL;
1645  delete break_access_;
1646  break_access_ = NULL;
1647  delete debugger_access_;
1648  debugger_access_ = NULL;
1649 
1650  delete compilation_cache_;
1651  compilation_cache_ = NULL;
1652  delete bootstrapper_;
1653  bootstrapper_ = NULL;
1654  delete inner_pointer_to_code_cache_;
1655  inner_pointer_to_code_cache_ = NULL;
1656  delete write_input_buffer_;
1657  write_input_buffer_ = NULL;
1658 
1659  delete context_switcher_;
1660  context_switcher_ = NULL;
1661  delete thread_manager_;
1662  thread_manager_ = NULL;
1663 
1664  delete string_tracker_;
1665  string_tracker_ = NULL;
1666 
1667  delete memory_allocator_;
1668  memory_allocator_ = NULL;
1669  delete code_range_;
1670  code_range_ = NULL;
1671  delete global_handles_;
1672  global_handles_ = NULL;
1673 
1674  delete external_reference_table_;
1675  external_reference_table_ = NULL;
1676 
1677 #ifdef ENABLE_DEBUGGER_SUPPORT
1678  delete debugger_;
1679  debugger_ = NULL;
1680  delete debug_;
1681  debug_ = NULL;
1682 #endif
1683 }
1684 
1685 
1686 void Isolate::InitializeThreadLocal() {
1687  thread_local_top_.isolate_ = this;
1688  thread_local_top_.Initialize();
1689 }
1690 
1691 
1692 void Isolate::PropagatePendingExceptionToExternalTryCatch() {
1693  ASSERT(has_pending_exception());
1694 
1695  bool external_caught = IsExternallyCaught();
1696  thread_local_top_.external_caught_exception_ = external_caught;
1697 
1698  if (!external_caught) return;
1699 
1700  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
1701  // Do not propagate OOM exception: we should kill VM asap.
1702  } else if (thread_local_top_.pending_exception_ ==
1703  heap()->termination_exception()) {
1704  try_catch_handler()->can_continue_ = false;
1705  try_catch_handler()->exception_ = heap()->null_value();
1706  } else {
1707  // At this point all non-object (failure) exceptions have
1708  // been dealt with so this shouldn't fail.
1709  ASSERT(!pending_exception()->IsFailure());
1710  try_catch_handler()->can_continue_ = true;
1711  try_catch_handler()->exception_ = pending_exception();
1712  if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
1713  try_catch_handler()->message_ = thread_local_top_.pending_message_obj_;
1714  }
1715  }
1716 }
1717 
1718 
1719 void Isolate::InitializeLoggingAndCounters() {
1720  if (logger_ == NULL) {
1721  logger_ = new Logger;
1722  }
1723  if (counters_ == NULL) {
1724  counters_ = new Counters;
1725  }
1726 }
1727 
1728 
1729 void Isolate::InitializeDebugger() {
1730 #ifdef ENABLE_DEBUGGER_SUPPORT
1731  ScopedLock lock(debugger_access_);
1732  if (NoBarrier_Load(&debugger_initialized_)) return;
1733  InitializeLoggingAndCounters();
1734  debug_ = new Debug(this);
1735  debugger_ = new Debugger(this);
1736  Release_Store(&debugger_initialized_, true);
1737 #endif
1738 }
1739 
1740 
1741 bool Isolate::Init(Deserializer* des) {
1742  ASSERT(state_ != INITIALIZED);
1743  ASSERT(Isolate::Current() == this);
1744  TRACE_ISOLATE(init);
1745 
1746 #ifdef DEBUG
1747  // The initialization process does not handle memory exhaustion.
1748  DisallowAllocationFailure disallow_allocation_failure;
1749 #endif
1750 
1751  InitializeLoggingAndCounters();
1752 
1753  InitializeDebugger();
1754 
1755  memory_allocator_ = new MemoryAllocator(this);
1756  code_range_ = new CodeRange(this);
1757 
1758  // Safe after setting Heap::isolate_, initializing StackGuard and
1759  // ensuring that Isolate::Current() == this.
1760  heap_.SetStackLimits();
1761 
1762 #define ASSIGN_ELEMENT(CamelName, hacker_name) \
1763  isolate_addresses_[Isolate::k##CamelName##Address] = \
1764  reinterpret_cast<Address>(hacker_name##_address());
1766 #undef C
1767 
1768  string_tracker_ = new StringTracker();
1769  string_tracker_->isolate_ = this;
1770  compilation_cache_ = new CompilationCache(this);
1771  transcendental_cache_ = new TranscendentalCache();
1772  keyed_lookup_cache_ = new KeyedLookupCache();
1773  context_slot_cache_ = new ContextSlotCache();
1774  descriptor_lookup_cache_ = new DescriptorLookupCache();
1775  unicode_cache_ = new UnicodeCache();
1776  inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
1777  write_input_buffer_ = new StringInputBuffer();
1778  global_handles_ = new GlobalHandles(this);
1779  bootstrapper_ = new Bootstrapper();
1780  handle_scope_implementer_ = new HandleScopeImplementer(this);
1781  stub_cache_ = new StubCache(this, zone());
1782  regexp_stack_ = new RegExpStack();
1783  regexp_stack_->isolate_ = this;
1784  date_cache_ = new DateCache();
1785 
1786  // Enable logging before setting up the heap
1787  logger_->SetUp();
1788 
1789  CpuProfiler::SetUp();
1790  HeapProfiler::SetUp();
1791 
1792  // Initialize other runtime facilities
1793 #if defined(USE_SIMULATOR)
1794 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
1795  Simulator::Initialize(this);
1796 #endif
1797 #endif
1798 
1799  { // NOLINT
1800  // Ensure that the thread has a valid stack guard. The v8::Locker object
1801  // will ensure this too, but we don't have to use lockers if we are only
1802  // using one thread.
1803  ExecutionAccess lock(this);
1804  stack_guard_.InitThread(lock);
1805  }
1806 
1807  // SetUp the object heap.
1808  const bool create_heap_objects = (des == NULL);
1809  ASSERT(!heap_.HasBeenSetUp());
1810  if (!heap_.SetUp(create_heap_objects)) {
1811  V8::SetFatalError();
1812  return false;
1813  }
1814 
1815  InitializeThreadLocal();
1816 
1817  bootstrapper_->Initialize(create_heap_objects);
1818  builtins_.SetUp(create_heap_objects);
1819 
1820  // Only preallocate on the first initialization.
1821  if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
1822  // Start the thread which will set aside some memory.
1823  PreallocatedMemoryThreadStart();
1824  preallocated_message_space_ =
1826  preallocated_memory_thread_->data(),
1827  preallocated_memory_thread_->length());
1828  PreallocatedStorageInit(preallocated_memory_thread_->length() / 4);
1829  }
1830 
1831  if (FLAG_preemption) {
1832  v8::Locker locker;
1834  }
1835 
1836 #ifdef ENABLE_DEBUGGER_SUPPORT
1837  debug_->SetUp(create_heap_objects);
1838 #endif
1839 
1840  // If we are deserializing, read the state into the now-empty heap.
1841  if (des != NULL) {
1842  des->Deserialize();
1843  }
1844  stub_cache_->Initialize();
1845 
1846  // Finish initialization of ThreadLocal after deserialization is done.
1847  clear_pending_exception();
1848  clear_pending_message();
1849  clear_scheduled_exception();
1850 
1851  // Deserializing may put strange things in the root array's copy of the
1852  // stack guard.
1853  heap_.SetStackLimits();
1854 
1855  // Quiet the heap NaN if needed on target platform.
1856  if (des != NULL) Assembler::QuietNaN(heap_.nan_value());
1857 
1858  deoptimizer_data_ = new DeoptimizerData;
1859  runtime_profiler_ = new RuntimeProfiler(this);
1860  runtime_profiler_->SetUp();
1861 
1862  // If we are deserializing, log non-function code objects and compiled
1863  // functions found in the snapshot.
1864  if (des != NULL && (FLAG_log_code || FLAG_ll_prof)) {
1865  HandleScope scope;
1866  LOG(this, LogCodeObjects());
1867  LOG(this, LogCompiledFunctions());
1868  }
1869 
1870  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, state_)),
1871  Internals::kIsolateStateOffset);
1872  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, embedder_data_)),
1873  Internals::kIsolateEmbedderDataOffset);
1874  CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)),
1875  Internals::kIsolateRootsOffset);
1876 
1877  state_ = INITIALIZED;
1878  time_millis_at_init_ = OS::TimeCurrentMillis();
1879  return true;
1880 }
1881 
1882 
1883 // Initialized lazily to allow early
1884 // v8::V8::SetAddHistogramSampleFunction calls.
1885 StatsTable* Isolate::stats_table() {
1886  if (stats_table_ == NULL) {
1887  stats_table_ = new StatsTable;
1888  }
1889  return stats_table_;
1890 }
1891 
1892 
1893 void Isolate::Enter() {
1894  Isolate* current_isolate = NULL;
1895  PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
1896  if (current_data != NULL) {
1897  current_isolate = current_data->isolate_;
1898  ASSERT(current_isolate != NULL);
1899  if (current_isolate == this) {
1900  ASSERT(Current() == this);
1901  ASSERT(entry_stack_ != NULL);
1902  ASSERT(entry_stack_->previous_thread_data == NULL ||
1903  entry_stack_->previous_thread_data->thread_id().Equals(
1904  ThreadId::Current()));
1905  // Same thread re-enters the isolate, no need to re-init anything.
1906  entry_stack_->entry_count++;
1907  return;
1908  }
1909  }
1910 
1911  // Threads can have default isolate set into TLS as Current but not yet have
1912  // PerIsolateThreadData for it, as it requires more advanced phase of the
1913  // initialization. For example, a thread might be the one that system used for
1914  // static initializers - in this case the default isolate is set in TLS but
1915  // the thread did not yet Enter the isolate. If PerisolateThreadData is not
1916  // there, use the isolate set in TLS.
1917  if (current_isolate == NULL) {
1918  current_isolate = Isolate::UncheckedCurrent();
1919  }
1920 
1921  PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
1922  ASSERT(data != NULL);
1923  ASSERT(data->isolate_ == this);
1924 
1925  EntryStackItem* item = new EntryStackItem(current_data,
1926  current_isolate,
1927  entry_stack_);
1928  entry_stack_ = item;
1929 
1930  SetIsolateThreadLocals(this, data);
1931 
1932  // In case it's the first time some thread enters the isolate.
1933  set_thread_id(data->thread_id());
1934 }
1935 
1936 
1937 void Isolate::Exit() {
1938  ASSERT(entry_stack_ != NULL);
1939  ASSERT(entry_stack_->previous_thread_data == NULL ||
1940  entry_stack_->previous_thread_data->thread_id().Equals(
1941  ThreadId::Current()));
1942 
1943  if (--entry_stack_->entry_count > 0) return;
1944 
1945  ASSERT(CurrentPerIsolateThreadData() != NULL);
1946  ASSERT(CurrentPerIsolateThreadData()->isolate_ == this);
1947 
1948  // Pop the stack.
1949  EntryStackItem* item = entry_stack_;
1950  entry_stack_ = item->previous_item;
1951 
1952  PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
1953  Isolate* previous_isolate = item->previous_isolate;
1954 
1955  delete item;
1956 
1957  // Reinit the current thread for the isolate it was running before this one.
1958  SetIsolateThreadLocals(previous_isolate, previous_thread_data);
1959 }
1960 
1961 
1962 #ifdef DEBUG
1963 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \
1964 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
1965 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1966 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1967 #undef ISOLATE_FIELD_OFFSET
1968 #endif
1969 
1970 } } // namespace v8::internal
byte * Address
Definition: globals.h:172
Object * context() const
Definition: frames-inl.h:163
void TraceException(bool flag)
Definition: isolate.cc:1240
#define CHECK_NOT_EMPTY_HANDLE(isolate, call)
Definition: isolate.h:127
Failure * StackOverflow()
Definition: isolate.cc:897
static void * GetThreadLocal(LocalStorageKey key)
Handle< JSObject > NewJSObject(Handle< JSFunction > constructor, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:973
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:186
MaybeObject * pending_exception()
Definition: isolate.h:535
static void IsolateEnteredJS(Isolate *isolate)
static String * cast(Object *obj)
void ScheduleThrow(Object *exception)
Definition: isolate.cc:944
StateTag current_vm_state()
Definition: isolate.h:991
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:973
#define LOG(isolate, Call)
Definition: log.h:81
void ReportFailedAccessCheck(JSObject *receiver, v8::AccessType type)
Definition: isolate.cc:747
StackTraceOptions
Definition: v8.h:763
Handle< JSArray > NewJSArray(int capacity, ElementsKind elements_kind=TERMINAL_FAST_ELEMENTS_KIND, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1005
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
bool MayNamedAccess(JSObject *receiver, Object *key, v8::AccessType type)
Definition: isolate.cc:801
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:1021
bool(* IndexedSecurityCallback)(Local< Object > host, uint32_t index, AccessType type, Local< Value > data)
Definition: v8.h:2124
void DoThrow(Object *exception, MessageLocation *location)
Definition: isolate.cc:1057
void mark_out_of_memory()
Definition: isolate.h:1421
Bootstrapper * bootstrapper()
Definition: isolate.h:803
static Failure * Exception()
Definition: objects-inl.h:1016
Failure * ReThrow(MaybeObject *exception)
Definition: isolate.cc:924
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:617
Context * global_context()
Definition: contexts.cc:58
Address address() const
Definition: ic-inl.h:41
#define ASSERT(condition)
Definition: checks.h:270
static PerIsolateThreadData * CurrentPerIsolateThreadData()
Definition: isolate.h:431
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback)
Definition: isolate.cc:741
static StackGuard * GetDefaultIsolateStackGuard()
Definition: isolate.cc:393
static Script * cast(Object *obj)
void clear_pending_exception()
Definition: isolate.h:548
static Context * cast(Object *context)
Definition: contexts.h:207
#define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)
void clear_scheduled_exception()
Definition: isolate.h:602
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:977
static int GetThreadLocalInt(LocalStorageKey key)
Definition: platform.h:468
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:3551
Handle< String > ToString()
static Smi * cast(Object *object)
void(* FailedAccessCheckCallback)(Local< Object > target, AccessType type, Local< Value > data)
Definition: v8.h:2697
void clear_pending_message()
Definition: isolate.h:557
void CaptureAndSetCurrentStackTraceFor(Handle< JSObject > error_object)
Definition: isolate.cc:530
StackGuard * stack_guard()
Definition: isolate.h:819
void Add(Vector< const char > format, Vector< FmtElm > elms)
Handle< Context > global_context()
Definition: isolate.cc:1318
bool OptionalRescheduleException(bool is_bottom_call)
Definition: isolate.cc:1245
Object * receiver() const
Definition: frames-inl.h:216
Address try_catch_handler_address()
Definition: isolate.h:565
static void Abort()
static void EnsureDefaultIsolate()
Definition: isolate.cc:363
T * start() const
Definition: utils.h:389
void ReportPendingMessages()
Definition: isolate.cc:1203
#define ISOLATE_INIT_LIST(V)
Definition: isolate.h:320
static JSGlobalProxy * cast(Object *obj)
static Address c_entry_fp(ThreadLocalTop *thread)
Definition: isolate.h:614
#define OFFSET_OF(type, field)
Definition: globals.h:287
v8::TryCatch * try_catch_handler()
Definition: isolate.h:562
static ThreadId Current()
Definition: isolate.h:153
static Failure * cast(MaybeObject *object)
Definition: objects-inl.h:485
void ComputeLocation(MessageLocation *target)
Definition: isolate.cc:990
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static void EnterDefaultIsolate()
Definition: isolate.cc:399
const int kPointerSize
Definition: globals.h:234
MaybeObject * scheduled_exception()
Definition: isolate.h:595
static LocalStorageKey CreateThreadLocalKey()
void PrintCurrentStackTrace(FILE *out)
Definition: isolate.cc:962
void Iterate(ObjectVisitor *v)
Definition: isolate.cc:475
Handle< JSArray > CaptureCurrentStackTrace(int frame_limit, StackTrace::StackTraceOptions options)
Definition: isolate.cc:542
Handle< JSValue > GetScriptWrapper(Handle< Script > script)
Definition: handles.cc:366
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:321
static Handle< Object > SetLocalPropertyIgnoreAttributes(Handle< JSObject > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes)
Definition: objects.cc:2924
const Register pc
int length() const
Definition: utils.h:383
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:554
AccessType
Definition: v8.h:2101
void * PreallocatedStorageNew(size_t size)
Definition: isolate.cc:257
void SetCaptureStackTraceForUncaughtExceptions(bool capture, int frame_limit, StackTrace::StackTraceOptions options)
Definition: isolate.cc:1291
Handle< JSBuiltinsObject > js_builtins_object()
Definition: isolate.h:646
Failure * Throw(Object *exception, MessageLocation *location=NULL)
Definition: isolate.cc:918
Handle< Script > script() const
Definition: messages.h:77
void Release_Store(volatile Atomic32 *ptr, Atomic32 value)
friend class ThreadId
Definition: isolate.h:1277
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static JSArray * cast(Object *obj)
Context * context()
Definition: isolate.h:518
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:954
virtual void VisitThread(Isolate *isolate, ThreadLocalTop *top)=0
bool IsOutOfMemoryException() const
Definition: objects-inl.h:999
bool is_null() const
Definition: handles.h:87
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C)
Definition: isolate.h:137
void IterateThread(ThreadVisitor *v)
Definition: isolate.cc:429
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:773
static AccessCheckInfo * cast(Object *obj)
String * hidden_symbol()
Definition: heap.h:1149
static void IsolateExitedJS(Isolate *isolate)
static void SetThreadLocal(LocalStorageKey key, void *value)
Handle< String > StackTraceString()
Definition: isolate.cc:502
void set_pending_exception(MaybeObject *exception)
Definition: isolate.h:545
virtual void Signal()=0
static void PrintError(const char *format,...)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kThisPropertyAssignmentsOffset flag
Definition: objects-inl.h:3682
bool(* NamedSecurityCallback)(Local< Object > host, Local< Value > key, AccessType type, Local< Value > data)
Definition: v8.h:2114
#define TRACE_ISOLATE(tag)
Definition: isolate.cc:1437
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
bool MayIndexedAccess(JSObject *receiver, uint32_t index, v8::AccessType type)
Definition: isolate.cc:851
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 true
Definition: flags.cc:157
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:1719
void UnregisterTryCatchHandler(v8::TryCatch *that)
Definition: isolate.cc:493
Failure * TerminateExecution()
Definition: isolate.cc:912
char * ArchiveThread(char *to)
Definition: isolate.cc:1346
Object * GetHiddenProperty(String *key)
Definition: objects.cc:3528
Failure * ThrowIllegalOperation()
Definition: isolate.cc:939
virtual void Wait()=0
static ThreadId Invalid()
Definition: isolate.h:156
static Handle< String > GetStackTraceLine(Handle< Object > recv, Handle< JSFunction > fun, Handle< Object > pos, Handle< Object > is_global)
Definition: execution.cc:765
Handle< Context > GetCallingGlobalContext()
Definition: isolate.cc:1324
void RegisterTryCatchHandler(v8::TryCatch *that)
Definition: isolate.cc:481
bool is_catchable_by_javascript(MaybeObject *exception)
Definition: isolate.h:608
static const int kMaxInliningLevels
Definition: compiler.h:278
int32_t Atomic32
Definition: atomicops.h:57
char * RestoreThread(char *from)
Definition: isolate.cc:1360
static void ClearMentionedObjectCache()
bool has_scheduled_exception()
Definition: isolate.h:599
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:1008
ThreadLocalTop * thread_local_top()
Definition: isolate.h:824
static void StopPreemption()
Definition: v8threads.cc:147
static const char *const kStackOverflowMessage
Definition: isolate.h:770
static void SetThreadLocalInt(LocalStorageKey key, int value)
Definition: platform.h:472
Handle< GlobalObject > global()
Definition: isolate.h:637
static JSObject * cast(Object *obj)
FlagType type() const
Definition: flags.cc:1358
#define ISOLATE_INIT_ARRAY_LIST(V)
Definition: isolate.h:308
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
#define ASSIGN_ELEMENT(CamelName, hacker_name)
static JSFunction * cast(Object *obj)