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