isolate.h revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifndef V8_ISOLATE_H_
644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define V8_ISOLATE_H_
744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <queue>
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-debug.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assert-scope.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/atomicops.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/builtins.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/contexts.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/date.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/execution.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/frames.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/handles.h"
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hashmap.h"
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/heap.h"
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/optimizing-compiler-thread.h"
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/regexp-stack.h"
24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime.h"
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime-profiler.h"
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/zone.h"
2744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2844f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace v8 {
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace base {
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RandomNumberGenerator;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3444f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal {
3544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass BasicBlockProfiler;
3744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Bootstrapper;
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CallInterfaceDescriptorData;
3944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CodeGenerator;
4044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CodeRange;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeStubDescriptor;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeTracer;
4344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CompilationCache;
44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass CompilationStatistics;
4544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ContextSlotCache;
4644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Counters;
4744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CpuFeatures;
4844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CpuProfiler;
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass DeoptimizerData;
5044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Deserializer;
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass EmptyStatement;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ExternalCallbackScope;
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ExternalReferenceTable;
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Factory;
5544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass FunctionInfoListener;
5644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass HandleScopeImplementer;
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass HeapProfiler;
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HStatistics;
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HTracer;
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass InlineRuntimeFunctionsTable;
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass InnerPointerToCodeCache;
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MaterializedObjectStore;
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeAgingHelper;
6444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass RegExpStack;
6544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass SaveContext;
6644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StringTracker;
6744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StubCache;
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SweeperThread;
6944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ThreadManager;
7044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ThreadState;
7144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ThreadVisitor;  // Defined in v8threads.h
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UnicodeCache;
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <StateTag Tag> class VMState;
7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// 'void function pointer', used to roundtrip the
7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// ExternalReference::ExternalReferenceRedirector since we can not include
7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// assembler.h, where it is defined, here.
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktypedef void* ExternalReferenceRedirectorPointer();
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
8144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Debug;
8244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Debugger;
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PromiseOnStack;
8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS64
8944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Redirection;
9044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Simulator;
9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Static indirection table for handles to constants.  If a frame
9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// element represents a constant, the data contains an index into
9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// this table of handles to the actual constants.
9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Static indirection table for handles to constants.  If a Result
9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// represents a constant, the data contains an index into this table
9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// of handles to the actual constants.
10044f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktypedef ZoneList<Handle<Object> > ZoneObjectList;
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate)    \
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  do {                                                    \
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Isolate* __isolate__ = (isolate);                     \
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (__isolate__->has_scheduled_exception()) {         \
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return __isolate__->PromoteScheduledException();    \
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }                                                     \
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } while (false)
10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Macros for MaybeHandle.
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, value) \
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {                                                      \
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* __isolate__ = (isolate);                       \
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (__isolate__->has_scheduled_exception()) {           \
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __isolate__->PromoteScheduledException();             \
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return value;                                         \
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }                                                       \
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (false)
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, T) \
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, MaybeHandle<T>())
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)  \
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {                                                               \
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!(call).ToHandle(&dst)) {                                    \
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK((isolate)->has_pending_exception());                    \
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return value;                                                  \
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }                                                                \
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } while (false)
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)  \
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION_VALUE(                             \
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, dst, call, isolate->heap()->exception())
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T)  \
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, MaybeHandle<T>())
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define THROW_NEW_ERROR(isolate, call, T)                                    \
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {                                                                       \
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> __error__;                                                \
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSIGN_RETURN_ON_EXCEPTION(isolate, __error__, isolate->factory()->call, \
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               T);                                           \
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return isolate->Throw<T>(__error__);                                     \
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } while (false)
14644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)             \
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {                                                            \
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> __error__;                                     \
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, __error__,        \
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       isolate->factory()->call); \
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return isolate->Throw(*__error__);                            \
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (false)
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RETURN_ON_EXCEPTION_VALUE(isolate, call, value)            \
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {                                                             \
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((call).is_null()) {                                        \
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK((isolate)->has_pending_exception());                  \
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return value;                                                \
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }                                                              \
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (false)
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RETURN_FAILURE_ON_EXCEPTION(isolate, call)  \
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RETURN_ON_EXCEPTION_VALUE(isolate, call, isolate->heap()->exception())
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define RETURN_ON_EXCEPTION(isolate, call, T)  \
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RETURN_ON_EXCEPTION_VALUE(isolate, call, MaybeHandle<T>())
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
170589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                \
171589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  C(Handler, handler)                                   \
172589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  C(CEntryFP, c_entry_fp)                               \
173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  C(CFunction, c_function)                              \
174589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  C(Context, context)                                   \
175589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  C(PendingException, pending_exception)                \
176589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  C(ExternalCaughtException, external_caught_exception) \
177589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  C(JSEntrySP, js_entry_sp)
17844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
17944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Platform-independent, reliable thread identifier.
1818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass ThreadId {
1828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public:
1838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Creates an invalid ThreadId.
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ThreadId() { base::NoBarrier_Store(&id_, kInvalidId); }
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ThreadId& operator=(const ThreadId& other) {
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    base::NoBarrier_Store(&id_, base::NoBarrier_Load(&other.id_));
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return *this;
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Returns ThreadId for current thread.
1928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
1938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Returns invalid ThreadId (guaranteed not to be equal to any thread).
1958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static ThreadId Invalid() { return ThreadId(kInvalidId); }
1968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Compares ThreadIds for equality.
1988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  INLINE(bool Equals(const ThreadId& other) const) {
199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return base::NoBarrier_Load(&id_) == base::NoBarrier_Load(&other.id_);
2008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
2018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Checks whether this ThreadId refers to any thread.
2038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  INLINE(bool IsValid() const) {
204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return base::NoBarrier_Load(&id_) != kInvalidId;
2058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
2068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Converts ThreadId to an integer representation
2088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // (required for public API: V8::V8::GetCurrentThreadId).
209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int ToInteger() const { return static_cast<int>(base::NoBarrier_Load(&id_)); }
2108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Converts ThreadId to an integer representation
2128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // (required for public API: V8::V8::TerminateExecution).
2138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static ThreadId FromInteger(int id) { return ThreadId(id); }
2148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private:
2168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static const int kInvalidId = -1;
2178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit ThreadId(int id) { base::NoBarrier_Store(&id_, id); }
2198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static int AllocateThreadId();
2218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static int GetCurrentThreadId();
2238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  base::Atomic32 id_;
2258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Atomic32 highest_thread_id_;
2278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  friend class Isolate;
2298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch};
2308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define FIELD_ACCESSOR(type, name)                 \
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void set_##name(type v) { name##_ = v; }  \
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline type name() const { return name##_; }
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ThreadLocalTop BASE_EMBEDDED {
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
2398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Does early low-level initialization that does not depend on the
2408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // isolate being present.
2418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ThreadLocalTop();
2428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Initialize the thread data.
24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Initialize();
24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Get the top C++ try catch handler or NULL if none are registered.
24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This method is not guaranteed to return an address that can be
24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // used for comparison with addresses into the JS stack.  If such an
25044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // address is needed, use try_catch_handler_address.
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FIELD_ACCESSOR(v8::TryCatch*, try_catch_handler)
25244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Get the address of the top C++ try catch handler or NULL if
25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // none are registered.
25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //
25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // This method always returns an address that can be compared to
25744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // pointers into the JavaScript stack.  When running on actual
25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // hardware, try_catch_handler_address and TryCatchHandler return
25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the same pointer.  When running on a simulator with a separate JS
26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // stack, try_catch_handler_address returns a JS stack address that
26144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // corresponds to the place on the JS stack where the C++ handler
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // would have been if the stack were not separate.
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address try_catch_handler_address() {
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::TryCatch::JSStackComparableAddress(try_catch_handler()));
26644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Free();
26944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Isolate* isolate_;
27144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The context where the current execution method is created and for variable
27244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // lookups.
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context* context_;
2748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ThreadId thread_id_;
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* pending_exception_;
27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool has_pending_message_;
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool rethrowing_message_;
27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* pending_message_obj_;
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* pending_message_script_;
28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int pending_message_start_pos_;
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int pending_message_end_pos_;
28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Use a separate value for scheduled exceptions to preserve the
28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // invariants that hold about pending_exception.  We may want to
28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // unify them later.
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* scheduled_exception_;
28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool external_caught_exception_;
28744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SaveContext* save_context_;
28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::TryCatch* catcher_;
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Stack.
29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address c_entry_fp_;  // the frame pointer of the top c entry frame
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address handler_;   // try-blocks are chained through the stack
293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Address c_function_;  // C function that was called at c entry.
29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Throwing an exception may cause a Promise rejection.  For this purpose
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we keep track of a stack of nested promises and the corresponding
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // try-catch handlers.
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PromiseOnStack* promise_on_stack_;
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef USE_SIMULATOR
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Simulator* simulator_;
30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address js_entry_sp_;  // the stack pointer of the bottom JS entry frame
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the external callback we're currently in
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalCallbackScope* external_callback_scope_;
30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StateTag current_vm_state_;
30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Generated code scratch locations.
31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t formal_count_;
31144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Call back function to report unsafe JS accesses.
31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::FailedAccessCheckCallback failed_access_check_callback_;
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Head of the list of live LookupResults.
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LookupResult* top_lookup_result_;
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
3198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void InitializeInternal();
3208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::TryCatch* try_catch_handler_;
32244f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    V8_TARGET_ARCH_ARM64 && !defined(__aarch64__) || \
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    V8_TARGET_ARCH_MIPS && !defined(__mips__) || \
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    V8_TARGET_ARCH_MIPS64 && !defined(__mips__)
32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ISOLATE_INIT_SIMULATOR_LIST(V)                                         \
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(bool, simulator_initialized, false)                                        \
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(HashMap*, simulator_i_cache, NULL)                                         \
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Redirection*, simulator_redirection, NULL)
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ISOLATE_INIT_SIMULATOR_LIST(V)
33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)                                       \
34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(CommentStatistic, paged_space_comments_statistics,                         \
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CommentStatistic::kMaxComments + 1)                                      \
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(int, code_kind_statistics, Code::NUMBER_OF_KINDS)
34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else
34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_INIT_ARRAY_LIST(V)                                             \
35444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* SerializerDeserializer state. */                                          \
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(int, bad_char_shift_table, kUC16AlphabetSize)                              \
35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(int, good_suffix_shift_table, (kBMMaxShift + 1))                           \
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(int, suffix_table, (kBMMaxShift + 1))                                      \
3593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(uint32_t, private_random_seed, 2)                                          \
36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef List<HeapObject*> DebugObjectCache;
36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_INIT_LIST(V)                                                   \
36544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* SerializerDeserializer state. */                                          \
36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(int, serialize_partial_snapshot_cache_length, 0)                           \
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(int, serialize_partial_snapshot_cache_capacity, 0)                         \
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Object**, serialize_partial_snapshot_cache, NULL)                          \
36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* Assembler state. */                                                       \
37044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(FatalErrorCallback, exception_behavior, NULL)                              \
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(LogEventCallback, event_logger, NULL)                                      \
372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL)     \
37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* To distinguish the function templates, so that we can find them in the */ \
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  /* function cache of the native context. */                                  \
37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(int, next_serial_number, 0)                                                \
37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL)  \
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* Part of the state of liveedit. */                                         \
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(FunctionInfoListener*, active_function_info_listener, NULL)                \
37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* State for Relocatable. */                                                 \
38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(Relocatable*, relocatable_top, NULL)                                       \
38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(DebugObjectCache*, string_stream_debug_object_cache, NULL)                 \
38244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(Object*, string_stream_current_security_token, NULL)                       \
38344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  /* Serializer state. */                                                      \
38444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(ExternalReferenceTable*, external_reference_table, NULL)                   \
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(int, pending_microtask_count, 0)                                           \
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(bool, autorun_microtasks, true)                                            \
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(HStatistics*, hstatistics, NULL)                                           \
388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  V(CompilationStatistics*, turbo_statistics, NULL)                            \
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(HTracer*, htracer, NULL)                                                   \
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CodeTracer*, code_tracer, NULL)                                            \
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(bool, fp_stubs_generated, false)                                           \
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(int, max_available_threads, 0)                                             \
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu)                            \
394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  V(PromiseRejectCallback, promise_reject_callback, NULL)                      \
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ISOLATE_INIT_SIMULATOR_LIST(V)
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define THREAD_LOCAL_TOP_ACCESSOR(type, name)                        \
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void set_##name(type v) { thread_local_top_.name##_ = v; }  \
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline type name() const { return thread_local_top_.name##_; }
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Isolate {
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // These forward declarations are required to make the friend declarations in
40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // PerIsolateThreadData work on some older versions of gcc.
40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  class ThreadDataTable;
40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  class EntryStackItem;
40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ~Isolate();
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // A thread has a PerIsolateThreadData instance for each isolate that it has
41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // entered. That instance is allocated when the isolate is initially entered
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // and reused on subsequent entries.
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  class PerIsolateThreadData {
41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block   public:
41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        : isolate_(isolate),
41744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          thread_id_(thread_id),
41844f0eee88ff00398ff7f715fab053374d808c90dSteve Block          stack_limit_(0),
41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block          thread_state_(NULL),
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS64
42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block          simulator_(NULL),
42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block          next_(NULL),
42744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          prev_(NULL) { }
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~PerIsolateThreadData();
42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate() const { return isolate_; }
43044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ThreadId thread_id() const { return thread_id_; }
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIELD_ACCESSOR(uintptr_t, stack_limit)
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIELD_ACCESSOR(ThreadState*, thread_state)
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS64
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIELD_ACCESSOR(Simulator*, simulator)
44044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    bool Matches(Isolate* isolate, ThreadId thread_id) const {
4438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      return isolate_ == isolate && thread_id_.Equals(thread_id);
44444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
44544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44644f0eee88ff00398ff7f715fab053374d808c90dSteve Block   private:
44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate_;
44844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ThreadId thread_id_;
44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    uintptr_t stack_limit_;
45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ThreadState* thread_state_;
45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    !defined(__mips__) && V8_TARGET_ARCH_MIPS64
45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Simulator* simulator_;
45744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
45844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
45944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PerIsolateThreadData* next_;
46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PerIsolateThreadData* prev_;
46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    friend class Isolate;
46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    friend class ThreadDataTable;
46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    friend class EntryStackItem;
46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
46944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  enum AddressId {
471589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
472589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_ENUM
474589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    kIsolateAddressCount
47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void InitializeOncePerProcess();
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the PerIsolateThreadData for the current thread (or NULL if one is
48044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // not currently set).
48144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static PerIsolateThreadData* CurrentPerIsolateThreadData() {
48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return reinterpret_cast<PerIsolateThreadData*>(
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        base::Thread::GetThreadLocal(per_isolate_thread_data_key_));
48444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the isolate inside which the current thread is running.
48744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  INLINE(static Isolate* Current()) {
488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(base::NoBarrier_Load(&isolate_key_created_) == 1);
48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate = reinterpret_cast<Isolate*>(
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        base::Thread::GetExistingThreadLocal(isolate_key_));
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(isolate != NULL);
49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate;
49344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
49444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  INLINE(static Isolate* UncheckedCurrent()) {
496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(base::NoBarrier_Load(&isolate_key_created_) == 1);
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Isolate*>(
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        base::Thread::GetThreadLocal(isolate_key_));
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Like UncheckedCurrent, but skips the check that |isolate_key_| was
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // initialized. Callers have to ensure that themselves.
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(static Isolate* UnsafeCurrent()) {
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Isolate*>(
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        base::Thread::GetThreadLocal(isolate_key_));
50644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
50869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Usually called by Init(), but can be called early e.g. to allow
50969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // testing components that require logging but not the whole
51069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // isolate.
51169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  //
51269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Safe to call more than once.
51369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void InitializeLoggingAndCounters();
51469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
51544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool Init(Deserializer* des);
51644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // True if at least one thread Enter'ed this isolate.
51844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool IsInUse() { return entry_stack_ != NULL; }
51944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Destroys the non-default isolates.
52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Sets default isolate into "has_been_disposed" state rather then destroying,
52244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // for legacy API reasons.
52344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void TearDown();
52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GlobalTearDown();
52644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Find the PerThread for this particular (isolate, thread) combination
528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If one does not yet exist, return null.
529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  PerIsolateThreadData* FindPerThreadDataForThisThread();
530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the PerThread for given (isolate, thread) combination
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If one does not yet exist, return null.
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PerIsolateThreadData* FindPerThreadDataForThread(ThreadId thread_id);
53444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
53544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the key used to store the pointer to the current isolate.
53644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Used internally for V8 threads that do not execute JavaScript but still
53744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // are part of the domain of an isolate (like the context switcher).
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Thread::LocalStorageKey isolate_key() {
53985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    return isolate_key_;
54085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  }
54144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
54244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the key used to store process-wide thread IDs.
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Thread::LocalStorageKey thread_id_key() {
54485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    return thread_id_key_;
54585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  }
54644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Thread::LocalStorageKey per_isolate_thread_data_key();
54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Mutex for serializing access to break control structures.
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::RecursiveMutex* break_access() { return &break_access_; }
55169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address get_address_from_id(AddressId id);
55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
55444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Access to top context (where the current function object was created).
55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context* context() { return thread_local_top_.context_; }
55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void set_context(Context* context) {
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(context == NULL || context->IsContext());
55844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    thread_local_top_.context_ = context;
55944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
56044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context** context_address() { return &thread_local_top_.context_; }
56144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(SaveContext*, save_context)
56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Access to current thread id.
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(ThreadId, thread_id)
56644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Interface to pending exception.
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* pending_exception() {
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(has_pending_exception());
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!thread_local_top_.pending_exception_->IsException());
57144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return thread_local_top_.pending_exception_;
57244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_pending_exception(Object* exception_obj) {
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!exception_obj->IsException());
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    thread_local_top_.pending_exception_ = exception_obj;
57744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void clear_pending_exception() {
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!thread_local_top_.pending_exception_->IsException());
58144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    thread_local_top_.pending_exception_ = heap_.the_hole_value();
58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** pending_exception_address() {
58544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &thread_local_top_.pending_exception_;
58644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool has_pending_exception() {
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!thread_local_top_.pending_exception_->IsException());
59044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return !thread_local_top_.pending_exception_->IsTheHole();
59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(bool, external_caught_exception)
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void clear_pending_message() {
59644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    thread_local_top_.has_pending_message_ = false;
59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    thread_local_top_.pending_message_script_ = heap_.the_hole_value();
59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
60044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::TryCatch* try_catch_handler() {
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return thread_local_top_.try_catch_handler();
60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address try_catch_handler_address() {
60444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return thread_local_top_.try_catch_handler_address();
60544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
60644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool* external_caught_exception_address() {
60744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &thread_local_top_.external_caught_exception_;
60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(v8::TryCatch*, catcher)
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** scheduled_exception_address() {
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return &thread_local_top_.scheduled_exception_;
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address pending_message_obj_address() {
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_);
6188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address has_pending_message_address() {
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(&thread_local_top_.has_pending_message_);
6228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
62344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address pending_message_script_address() {
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        &thread_local_top_.pending_message_script_);
62744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* scheduled_exception() {
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(has_scheduled_exception());
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!thread_local_top_.scheduled_exception_->IsException());
63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return thread_local_top_.scheduled_exception_;
63344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
63444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool has_scheduled_exception() {
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!thread_local_top_.scheduled_exception_->IsException());
6363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void clear_scheduled_exception() {
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!thread_local_top_.scheduled_exception_->IsException());
64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
64144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
64244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasExternalTryCatch();
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsFinallyOnTop();
64544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_catchable_by_javascript(Object* exception) {
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return exception != heap()->termination_exception();
64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Serializer.
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PushToPartialSnapshotCache(Object* obj);
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // JS execution stack (see frames.h).
65444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static Address c_entry_fp(ThreadLocalTop* thread) {
65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return thread->c_entry_fp_;
65644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Address c_function() { return thread_local_top_.c_function_; }
65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline Address* c_entry_fp_address() {
66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &thread_local_top_.c_entry_fp_;
66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline Address* handler_address() { return &thread_local_top_.handler_; }
664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline Address* c_function_address() {
665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return &thread_local_top_.c_function_;
666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
66744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Bottom JS entry.
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address js_entry_sp() {
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return thread_local_top_.js_entry_sp_;
67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline Address* js_entry_sp_address() {
67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &thread_local_top_.js_entry_sp_;
67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Generated code scratch locations.
67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void* formal_count_address() { return &thread_local_top_.formal_count_; }
67844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the global object of the current context. It could be
6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // a builtin object, or a JS global object.
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<GlobalObject> global_object() {
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<GlobalObject>(context()->global_object());
68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the global proxy object of the current context.
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSObject* global_proxy() {
68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return context()->global_proxy();
68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSBuiltinsObject> js_builtins_object() {
69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
69244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
69344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
69444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void FreeThreadResources() { thread_local_top_.Free(); }
69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
69744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // This method is called by the api after operations that may throw
69844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // exceptions.  If an exception was thrown and not handled by an external
69944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // handler the exception is scheduled to be rethrown when we return to running
70044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // JavaScript code.  If an exception is scheduled true is returned.
70144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool OptionalRescheduleException(bool is_bottom_call);
70244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Push and pop a promise and the current try-catch handler.
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PushPromise(Handle<JSObject> promise);
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PopPromise();
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> GetPromiseOnStackOnThrow();
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  class ExceptionScope {
7098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch   public:
7108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    explicit ExceptionScope(Isolate* isolate) :
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Scope currently can only be used for regular exceptions,
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // not termination exception.
7138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate_(isolate),
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pending_exception_(isolate_->pending_exception(), isolate_),
7158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      catcher_(isolate_->catcher())
7168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    { }
7178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ~ExceptionScope() {
7198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate_->set_catcher(catcher_);
7208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate_->set_pending_exception(*pending_exception_);
7218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
7228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
7238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch   private:
7248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Isolate* isolate_;
7258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Handle<Object> pending_exception_;
7268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    v8::TryCatch* catcher_;
7278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  };
7288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
72944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void SetCaptureStackTraceForUncaughtExceptions(
73044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      bool capture,
73144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int frame_limit,
73244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      StackTrace::StackTraceOptions options);
73344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void PrintCurrentStackTrace(FILE* out);
73544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void PrintStack(StringStream* accumulator);
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PrintStack(FILE* out);
73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<String> StackTraceString();
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Object* object,
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Map* map,
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      unsigned int magic2));
74244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSArray> CaptureCurrentStackTrace(
74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int frame_limit,
74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      StackTrace::StackTraceOptions options);
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> CaptureSimpleStackTrace(Handle<JSObject> error_object,
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Handle<Object> caller);
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CaptureAndSetSimpleStackTrace(Handle<JSObject> error_object,
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Handle<Object> caller);
750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSArray> GetDetailedStackTrace(Handle<JSObject> error_object);
751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSArray> GetDetailedFromSimpleStackTrace(
752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<JSObject> error_object);
7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
75444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns if the top context may access the given global object. If
75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the result is false, the pending exception is guaranteed to be
75644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // set.
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MayNamedAccess(Handle<JSObject> receiver,
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      Handle<Object> key,
76044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                      v8::AccessType type);
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MayIndexedAccess(Handle<JSObject> receiver,
76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        uint32_t index,
76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        v8::AccessType type);
764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsInternallyUsedPropertyName(Handle<Object> name);
765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsInternallyUsedPropertyName(Object* name);
76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReportFailedAccessCheck(Handle<JSObject> receiver, v8::AccessType type);
76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
77044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Exception throwing support. The caller should use the result
77144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // of Throw() as its return value.
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* Throw(Object* exception, MessageLocation* location = NULL);
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <typename T>
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MUST_USE_RESULT MaybeHandle<T> Throw(Handle<Object> exception,
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       MessageLocation* location = NULL) {
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Throw(*exception, location);
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MaybeHandle<T>();
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Re-throw an exception.  This involves no error reporting since
78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // error reporting was handled when the exception was thrown
78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // originally.
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* ReThrow(Object* exception);
78544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ScheduleThrow(Object* exception);
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Re-set pending message, script and positions reported to the TryCatch
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // back to the TLS for re-use when rethrowing.
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RestorePendingMessageFromTryCatch(v8::TryCatch* handler);
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Un-schedule an exception that was caught by a TryCatch handler.
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler);
79144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ReportPendingMessages();
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return pending location if any or unfilled structure.
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MessageLocation GetMessageLocation();
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* ThrowIllegalOperation();
79544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
79644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* PromoteScheduledException();
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DoThrow(Object* exception, MessageLocation* location);
79944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Checks if exception should be reported and finds out if it's
80044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // caught externally.
80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool ShouldReportException(bool* can_be_caught_externally,
80244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                             bool catchable_by_javascript);
80344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
80444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Attempts to compute the current source location, storing the
80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // result in the target out parameter.
80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ComputeLocation(MessageLocation* target);
807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool ComputeLocationFromStackTrace(MessageLocation* target,
808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     Handle<Object> exception);
809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSMessageObject> CreateMessage(Handle<Object> exception,
811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        MessageLocation* location);
81244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Out of resource exception helpers.
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* StackOverflow();
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* TerminateExecution();
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CancelTerminateExecution();
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void RequestInterrupt(InterruptCallback callback, void* data);
819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void InvokeApiInterruptCallbacks();
82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Administration
82244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Iterate(ObjectVisitor* v);
82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* Iterate(ObjectVisitor* v, char* t);
82544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void IterateThread(ThreadVisitor* v, char* t);
82644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
82744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Returns the current native context.
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Context> native_context();
83044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns the native context of the calling JavaScript code.  That
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is, the native context of the top-most JavaScript frame.
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Context> GetCallingNativeContext();
83444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
83544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void RegisterTryCatchHandler(v8::TryCatch* that);
83644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void UnregisterTryCatchHandler(v8::TryCatch* that);
83744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
83844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* ArchiveThread(char* to);
83944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* RestoreThread(char* from);
84044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
84144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const char* const kStackOverflowMessage;
84244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
84344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kUC16AlphabetSize = 256;  // See StringSearchBase.
84444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kBMMaxShift = 250;        // See StringSearchBase.
84544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
84644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Accessors.
84744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define GLOBAL_ACCESSOR(type, name, initialvalue)                       \
84844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline type name() const {                                            \
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
85044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return name##_;                                                     \
85144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }                                                                     \
85244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set_##name(type value) {                                  \
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
85444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    name##_ = value;                                                    \
85544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
85644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
85744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef GLOBAL_ACCESSOR
85844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
85944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define GLOBAL_ARRAY_ACCESSOR(type, name, length)                       \
86044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline type* name() {                                                 \
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
86244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &(name##_)[0];                                               \
86344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
86444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
86544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef GLOBAL_ARRAY_ACCESSOR
86644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name)            \
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<type> name() {                                             \
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<type>(native_context()->name(), this);            \
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }                                                                 \
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_##name(type* value) {                                     \
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return native_context()->is_##name(value);                      \
87344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef NATIVE_CONTEXT_FIELD_ACCESSOR
87644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
87744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Bootstrapper* bootstrapper() { return bootstrapper_; }
87869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Counters* counters() {
87969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Call InitializeLoggingAndCounters() if logging is needed before
88069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // the isolate is fully initialized.
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(counters_ != NULL);
88269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return counters_;
88369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
88444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeRange* code_range() { return code_range_; }
88544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
88644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CompilationCache* compilation_cache() { return compilation_cache_; }
88769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Logger* logger() {
88869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Call InitializeLoggingAndCounters() if logging is needed before
88969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // the isolate is fully initialized.
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(logger_ != NULL);
89169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return logger_;
89269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
89344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StackGuard* stack_guard() { return &stack_guard_; }
89444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap() { return &heap_; }
89569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  StatsTable* stats_table();
89644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StubCache* stub_cache() { return stub_cache_; }
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeAgingHelper* code_aging_helper() { return code_aging_helper_; }
89844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
89944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MaterializedObjectStore* materialized_object_store() {
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return materialized_object_store_;
90244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
90344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
90444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MemoryAllocator* memory_allocator() {
90544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return memory_allocator_;
90644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
90744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
90844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  KeyedLookupCache* keyed_lookup_cache() {
90944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return keyed_lookup_cache_;
91044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
91144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
91244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ContextSlotCache* context_slot_cache() {
91344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return context_slot_cache_;
91444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
91544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
91644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DescriptorLookupCache* descriptor_lookup_cache() {
91744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return descriptor_lookup_cache_;
91844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
91944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScopeData* handle_scope_data() { return &handle_scope_data_; }
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
92244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScopeImplementer* handle_scope_implementer() {
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(handle_scope_implementer_);
92444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return handle_scope_implementer_;
92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* runtime_zone() { return &runtime_zone_; }
92744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  UnicodeCache* unicode_cache() {
9298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return unicode_cache_;
93044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
93144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  InnerPointerToCodeCache* inner_pointer_to_code_cache() {
9333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return inner_pointer_to_code_cache_;
9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
93544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
93644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  GlobalHandles* global_handles() { return global_handles_; }
93744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EternalHandles* eternal_handles() { return eternal_handles_; }
93944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ThreadManager* thread_manager() { return thread_manager_; }
94144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
94244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StringTracker* string_tracker() { return string_tracker_; }
94344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
94444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
94544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &jsregexp_uncanonicalize_;
94644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
94744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
94844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
94944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &jsregexp_canonrange_;
95044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
95144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
95244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RuntimeState* runtime_state() { return &runtime_state_; }
95344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
95444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Builtins* builtins() { return &builtins_; }
95544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void NotifyExtensionInstalled() {
9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    has_installed_extensions_ = true;
9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_installed_extensions() { return has_installed_extensions_; }
9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
96244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::Ecma262Canonicalize>*
96344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      regexp_macro_assembler_canonicalize() {
96444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &regexp_macro_assembler_canonicalize_;
96544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
96644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
96744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RegExpStack* regexp_stack() { return regexp_stack_; }
96844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
96944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::Ecma262Canonicalize>*
97044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      interp_canonicalize_mapping() {
97144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &interp_canonicalize_mapping_;
97244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
97344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Debug* debug() { return debug_; }
97544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline bool DebuggerHasBreakPoints();
977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapProfiler* heap_profiler() const { return heap_profiler_; }
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
98144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
98244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HistogramInfo* heap_histograms() { return heap_histograms_; }
98344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
98444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  JSObject::SpillInformation* js_spill_information() {
98544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return &js_spill_information_;
98644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
98744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
98844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory() { return reinterpret_cast<Factory*>(this); }
99044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kJSRegexpStaticOffsetsVectorSize = 128;
99244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(ExternalCallbackScope*, external_callback_scope)
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(StateTag, current_vm_state)
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetData(uint32_t slot, void* data) {
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(slot < Internals::kNumIsolateDataSlots);
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    embedder_data_[slot] = data;
100044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* GetData(uint32_t slot) {
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(slot < Internals::kNumIsolateDataSlots);
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return embedder_data_[slot];
100444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
100544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  THREAD_LOCAL_TOP_ACCESSOR(LookupResult*, top_lookup_result)
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool serializer_enabled() const { return serializer_enabled_; }
100944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsDead() { return has_fatal_error_; }
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SignalFatalError() { has_fatal_error_ = true; }
101244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool use_crankshaft() const;
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool initialized_from_snapshot() { return initialized_from_snapshot_; }
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double time_millis_since_init() {
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return base::OS::TimeCurrentMillis() - time_millis_at_init_;
101944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
102044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DateCache* date_cache() {
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return date_cache_;
102344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_date_cache(DateCache* date_cache) {
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (date_cache != date_cache_) {
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      delete date_cache_;
102844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    date_cache_ = date_cache;
103044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
103144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* get_initial_js_array_map(ElementsKind kind);
1033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsFastArrayConstructorPrototypeChainIntact();
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallInterfaceDescriptorData* call_descriptor_data(int index);
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IterateDeferredHandles(ObjectVisitor* visitor);
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void LinkDeferredHandles(DeferredHandles* deferred_handles);
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsDeferredHandle(Object** location);
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool concurrent_recompilation_enabled() {
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Thread is only available with flag enabled.
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(optimizing_compiler_thread_ == NULL ||
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           FLAG_concurrent_recompilation);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return optimizing_compiler_thread_ != NULL;
10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool concurrent_osr_enabled() const {
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Thread is only available with flag enabled.
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(optimizing_compiler_thread_ == NULL ||
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           FLAG_concurrent_recompilation);
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return optimizing_compiler_thread_ != NULL && FLAG_concurrent_osr;
10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OptimizingCompilerThread* optimizing_compiler_thread() {
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return optimizing_compiler_thread_;
10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int id() const { return static_cast<int>(id_); }
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStatistics* GetHStatistics();
1067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationStatistics* GetTurboStatistics();
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HTracer* GetHTracer();
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeTracer* GetCodeTracer();
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void DumpAndResetCompilationStats();
1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FunctionEntryHook function_entry_hook() { return function_entry_hook_; }
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_function_entry_hook(FunctionEntryHook function_entry_hook) {
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    function_entry_hook_ = function_entry_hook;
10763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* stress_deopt_count_address() { return &stress_deopt_count_; }
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline base::RandomNumberGenerator* random_number_generator();
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Given an address occupied by a live code object, return that object.
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* FindCodeObject(Address a);
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int NextOptimizationId() {
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int id = next_optimization_id_++;
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!Smi::IsValid(next_optimization_id_)) {
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_optimization_id_ = 0;
10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return id;
10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get (and lazily initialize) the registry for per-isolate symbols.
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSObject> GetSymbolRegistry();
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddCallCompletedCallback(CallCompletedCallback callback);
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RemoveCallCompletedCallback(CallCompletedCallback callback);
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void FireCallCompletedCallback();
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void SetPromiseRejectCallback(PromiseRejectCallback callback);
1101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ReportPromiseReject(Handle<JSObject> promise, Handle<Object> value,
1102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           v8::PromiseRejectEvent event);
1103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void EnqueueMicrotask(Handle<Object> microtask);
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RunMicrotasks();
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetUseCounterCallback(v8::Isolate::UseCounterCallback callback);
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CountUsage(v8::Isolate::UseCounterFeature feature);
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BasicBlockProfiler* GetOrCreateBasicBlockProfiler();
1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BasicBlockProfiler* basic_block_profiler() { return basic_block_profiler_; }
1112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static Isolate* NewForTesting() { return new Isolate(false); }
1114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::string GetTurboCfgFileName();
1116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if TRACE_MAPS
1118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int GetNextUniqueSharedFunctionInfoId() { return next_unique_sfi_id_++; }
1119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit Isolate(bool enable_serializer);
112344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  friend struct GlobalState;
11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  friend struct InitializeGlobalState;
11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // These fields are accessed through the API, offsets must be kept in sync
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // with v8::internal::Internals (in include/v8.h) constants. This is also
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // verified in Isolate::Init() using runtime checks.
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* embedder_data_[Internals::kNumIsolateDataSlots];
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap heap_;
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The per-process lock should be acquired before the ThreadDataTable is
113444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // modified.
113544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  class ThreadDataTable {
113644f0eee88ff00398ff7f715fab053374d808c90dSteve Block   public:
113744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ThreadDataTable();
113844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ~ThreadDataTable();
113944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
114044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
114144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    void Insert(PerIsolateThreadData* data);
114244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    void Remove(PerIsolateThreadData* data);
11433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    void RemoveAllThreads(Isolate* isolate);
114444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
114544f0eee88ff00398ff7f715fab053374d808c90dSteve Block   private:
114644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PerIsolateThreadData* list_;
114744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
114844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
114944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // These items form a stack synchronously with threads Enter'ing and Exit'ing
115044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the Isolate. The top of the stack points to a thread which is currently
115144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // running the Isolate. When the stack is empty, the Isolate is considered
115244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // not entered by any thread and can be Disposed.
115344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // If the same thread enters the Isolate more then once, the entry_count_
115444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // is incremented rather then a new item pushed to the stack.
115544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  class EntryStackItem {
115644f0eee88ff00398ff7f715fab053374d808c90dSteve Block   public:
115744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EntryStackItem(PerIsolateThreadData* previous_thread_data,
115844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                   Isolate* previous_isolate,
115944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                   EntryStackItem* previous_item)
116044f0eee88ff00398ff7f715fab053374d808c90dSteve Block        : entry_count(1),
116144f0eee88ff00398ff7f715fab053374d808c90dSteve Block          previous_thread_data(previous_thread_data),
116244f0eee88ff00398ff7f715fab053374d808c90dSteve Block          previous_isolate(previous_isolate),
116344f0eee88ff00398ff7f715fab053374d808c90dSteve Block          previous_item(previous_item) { }
116444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
116544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int entry_count;
116644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PerIsolateThreadData* previous_thread_data;
116744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* previous_isolate;
116844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EntryStackItem* previous_item;
116944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
11703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch   private:
117144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
117344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::LazyMutex thread_data_table_mutex_;
117585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Thread::LocalStorageKey per_isolate_thread_data_key_;
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Thread::LocalStorageKey isolate_key_;
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Thread::LocalStorageKey thread_id_key_;
117985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  static ThreadDataTable* thread_data_table_;
118085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A global counter for all generated Isolates, might overflow.
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static base::Atomic32 isolate_counter_;
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if DEBUG
1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static base::Atomic32 isolate_key_created_;
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif
1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
118844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Deinit();
118944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
119044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static void SetIsolateThreadLocals(Isolate* isolate,
119144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                     PerIsolateThreadData* data);
119244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
119344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Find the PerThread for this particular (isolate, thread) combination.
119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // If one does not yet exist, allocate a new one.
119544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
119644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
119744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Initializes the current thread to run this Isolate.
119844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
119944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // at the same time, this should be prevented using external locking.
120044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Enter();
120144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
120244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Exits the current thread. The previosuly entered Isolate is restored
120344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // for the thread.
120444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
120544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // at the same time, this should be prevented using external locking.
120644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Exit();
120744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
120844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void InitializeThreadLocal();
120944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
121044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void MarkCompactPrologue(bool is_compacting,
121144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                           ThreadLocalTop* archived_thread_data);
121244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void MarkCompactEpilogue(bool is_compacting,
121344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                           ThreadLocalTop* archived_thread_data);
121444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
121544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void FillCache();
121644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Propagate pending exception message to the v8::TryCatch.
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If there is no external try-catch or message was successfully propagated,
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // then return true.
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool PropagatePendingExceptionToExternalTryCatch();
122169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Traverse prototype chain to find out whether the object is derived from
12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the Error object.
12243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsErrorObject(Handle<Object> obj);
12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::Atomic32 id_;
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EntryStackItem* entry_stack_;
122844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int stack_trace_nesting_level_;
122944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StringStream* incomplete_message_;
1230589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Address isolate_addresses_[kIsolateAddressCount + 1];  // NOLINT
123144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Bootstrapper* bootstrapper_;
123244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RuntimeProfiler* runtime_profiler_;
123344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CompilationCache* compilation_cache_;
123444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Counters* counters_;
123544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeRange* code_range_;
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::RecursiveMutex break_access_;
123744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Logger* logger_;
123844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StackGuard stack_guard_;
123944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StatsTable* stats_table_;
124044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StubCache* stub_cache_;
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeAgingHelper* code_aging_helper_;
124244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DeoptimizerData* deoptimizer_data_;
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MaterializedObjectStore* materialized_object_store_;
124444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ThreadLocalTop thread_local_top_;
124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool capture_stack_trace_for_uncaught_exceptions_;
124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int stack_trace_for_uncaught_exceptions_frame_limit_;
124744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
124844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MemoryAllocator* memory_allocator_;
124944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  KeyedLookupCache* keyed_lookup_cache_;
125044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ContextSlotCache* context_slot_cache_;
125144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DescriptorLookupCache* descriptor_lookup_cache_;
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScopeData handle_scope_data_;
125344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScopeImplementer* handle_scope_implementer_;
12548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  UnicodeCache* unicode_cache_;
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone runtime_zone_;
12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  InnerPointerToCodeCache* inner_pointer_to_code_cache_;
125744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  GlobalHandles* global_handles_;
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EternalHandles* eternal_handles_;
125944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ThreadManager* thread_manager_;
126044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RuntimeState runtime_state_;
126144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Builtins builtins_;
12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_installed_extensions_;
126344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StringTracker* string_tracker_;
126444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
126544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
126644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::Ecma262Canonicalize>
126744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      regexp_macro_assembler_canonicalize_;
126844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RegExpStack* regexp_stack_;
12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DateCache* date_cache_;
127044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallInterfaceDescriptorData* call_descriptor_data_;
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::RandomNumberGenerator* random_number_generator_;
127344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Whether the isolate has been created for snapshotting.
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool serializer_enabled_;
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // True if fatal error has been signaled for this isolate.
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_fatal_error_;
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // True if this isolate was initialized from a snapshot.
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool initialized_from_snapshot_;
12823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Time stamp at initialization.
12843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  double time_millis_at_init_;
12853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
128644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
128744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // A static array of histogram info for each type.
128844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HistogramInfo heap_histograms_[LAST_TYPE + 1];
128944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  JSObject::SpillInformation js_spill_information_;
129044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
129144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
129244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Debug* debug_;
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CpuProfiler* cpu_profiler_;
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapProfiler* heap_profiler_;
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FunctionEntryHook function_entry_hook_;
129644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  typedef std::pair<InterruptCallback, void*> InterruptEntry;
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::queue<InterruptEntry> api_interrupts_queue_;
1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
130044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
130144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  type name##_;
130244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
130344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef GLOBAL_BACKING_STORE
130444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
130544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define GLOBAL_ARRAY_BACKING_STORE(type, name, length)                         \
130644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  type name##_[length];
130744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
130844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef GLOBAL_ARRAY_BACKING_STORE
130944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
131044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
131144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // This class is huge and has a number of fields controlled by
131244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // preprocessor defines. Make sure the offsets of these fields agree
131344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // between compilation units.
131444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_FIELD_OFFSET(type, name, ignored)                              \
131544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const intptr_t name##_debug_offset_;
131644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
131744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
131844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef ISOLATE_FIELD_OFFSET
131944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
132044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeferredHandles* deferred_handles_head_;
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OptimizingCompilerThread* optimizing_compiler_thread_;
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Counts deopt points if deopt_every_n_times is enabled.
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned int stress_deopt_count_;
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int next_optimization_id_;
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if TRACE_MAPS
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int next_unique_sfi_id_;
1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif
1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // List of callbacks when a Call completes.
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<CallCompletedCallback> call_completed_callbacks_;
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Isolate::UseCounterCallback use_counter_callback_;
1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BasicBlockProfiler* basic_block_profiler_;
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class ExecutionAccess;
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HandleScopeImplementer;
134144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class IsolateInitializer;
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class OptimizingCompilerThread;
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class SweeperThread;
1344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  friend class ThreadManager;
1345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  friend class Simulator;
1346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  friend class StackGuard;
13478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  friend class ThreadId;
134869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  friend class TestMemoryAllocatorScope;
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class TestCodeRangeScope;
135044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class v8::Isolate;
135144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class v8::Locker;
1352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  friend class v8::Unlocker;
135344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
135444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_COPY_AND_ASSIGN(Isolate);
135544f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
135644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
135744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef FIELD_ACCESSOR
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef THREAD_LOCAL_TOP_ACCESSOR
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PromiseOnStack {
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PromiseOnStack(StackHandler* handler, Handle<JSObject> promise,
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 PromiseOnStack* prev)
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : handler_(handler), promise_(promise), prev_(prev) {}
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackHandler* handler() { return handler_; }
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSObject> promise() { return promise_; }
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PromiseOnStack* prev() { return prev_; }
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackHandler* handler_;
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSObject> promise_;
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PromiseOnStack* prev_;
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
137944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// class as a work around for a bug in the generated code found with these
138044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// versions of GCC. See V8 issue 122 for details.
138144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass SaveContext BASE_EMBEDDED {
138244f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline explicit SaveContext(Isolate* isolate);
138444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
138544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ~SaveContext() {
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->set_context(context_.is_null() ? NULL : *context_);
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->set_save_context(prev_);
138844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
138944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Context> context() { return context_; }
139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SaveContext* prev() { return prev_; }
139244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns true if this save context is below a given JavaScript frame.
13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsBelowFrame(JavaScriptFrame* frame) {
13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
139644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
139744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139844f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
140044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Context> context_;
140144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SaveContext* prev_;
14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address c_entry_fp_;
140344f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
140444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
140544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
140644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass AssertNoContextChange BASE_EMBEDDED {
140744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
140844f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit AssertNoContextChange(Isolate* isolate)
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : isolate_(isolate),
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      context_(isolate->context(), isolate) { }
141244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ~AssertNoContextChange() {
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(isolate_->context() == *context_);
141444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
141544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
141644f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
141844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Context> context_;
141944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else
142044f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit AssertNoContextChange(Isolate* isolate) { }
142244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
142344f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
142444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
142544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
142644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ExecutionAccess BASE_EMBEDDED {
142744f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
142844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
142944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Lock(isolate);
143044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
143144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ~ExecutionAccess() { Unlock(isolate_); }
143244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Lock(Isolate* isolate) { isolate->break_access()->Lock(); }
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Unlock(Isolate* isolate) { isolate->break_access()->Unlock(); }
143544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
143644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static bool TryLock(Isolate* isolate) {
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return isolate->break_access()->TryLock();
143844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
143944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
144044f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
144144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
144244f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
144344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
144444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support for checking for stack-overflows.
144644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StackLimitCheck BASE_EMBEDDED {
144744f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
144844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
144944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use this to check for stack-overflows in C++ code.
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool HasOverflowed() const {
145244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    StackGuard* stack_guard = isolate_->stack_guard();
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return GetCurrentStackPosition() < stack_guard->real_climit();
145444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use this to check for stack-overflow when entering runtime from JS code.
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool JsHasOverflowed() const;
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
145944f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
146044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
146144f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
146244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
146344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
146444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Support for temporarily postponing interrupts. When the outermost
146544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// postpone scope is left the interrupts will be re-enabled and any
146644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// interrupts that occurred while in the scope will be taken into
146744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// account.
146844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass PostponeInterruptsScope BASE_EMBEDDED {
146944f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PostponeInterruptsScope(Isolate* isolate,
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          int intercept_mask = StackGuard::ALL_INTERRUPTS)
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : stack_guard_(isolate->stack_guard()),
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        intercept_mask_(intercept_mask),
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        intercepted_flags_(0) {
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stack_guard_->PushPostponeInterruptsScope(this);
147644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
147744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
147844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ~PostponeInterruptsScope() {
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stack_guard_->PopPostponeInterruptsScope();
148044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the bottom-most scope that intercepts this interrupt.
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return whether the interrupt has been intercepted.
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Intercept(StackGuard::InterruptFlag flag);
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148644f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
148744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StackGuard* stack_guard_;
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int intercept_mask_;
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int intercepted_flags_;
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PostponeInterruptsScope* prev_;
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class StackGuard;
149344f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
149444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
149544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeTracer FINAL : public Malloced {
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit CodeTracer(int isolate_id)
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : file_(NULL),
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        scope_depth_(0) {
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!ShouldRedirect()) {
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      file_ = stdout;
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
150544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_redirect_code_traces_to == NULL) {
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SNPrintF(filename_,
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               "code-%d-%d.asm",
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               base::OS::GetCurrentProcessId(),
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               isolate_id);
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      StrNCpy(filename_, FLAG_redirect_code_traces_to, filename_.length());
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
151444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    WriteChars(filename_.start(), "", 0, false);
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
151744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class Scope {
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit Scope(CodeTracer* tracer) : tracer_(tracer) { tracer->OpenFile(); }
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~Scope() { tracer_->CloseFile();  }
152244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FILE* file() const { return tracer_->file(); }
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CodeTracer* tracer_;
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void OpenFile() {
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!ShouldRedirect()) {
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (file_ == NULL) {
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      file_ = base::OS::FOpen(filename_.start(), "a");
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    scope_depth_++;
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
154044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CloseFile() {
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!ShouldRedirect()) {
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (--scope_depth_ == 0) {
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      fclose(file_);
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      file_ = NULL;
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FILE* file() const { return file_; }
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool ShouldRedirect() {
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return FLAG_redirect_code_traces;
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedVector<char, 128> filename_;
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FILE* file_;
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int scope_depth_;
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
156344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
156444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} }  // namespace v8::internal
156544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
156644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif  // V8_ISOLATE_H_
1567