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