13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Redistribution and use in source and binary forms, with or without
344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// modification, are permitted provided that the following conditions are
444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// met:
544f0eee88ff00398ff7f715fab053374d808c90dSteve Block//
644f0eee88ff00398ff7f715fab053374d808c90dSteve Block//     * Redistributions of source code must retain the above copyright
744f0eee88ff00398ff7f715fab053374d808c90dSteve Block//       notice, this list of conditions and the following disclaimer.
844f0eee88ff00398ff7f715fab053374d808c90dSteve Block//     * Redistributions in binary form must reproduce the above
944f0eee88ff00398ff7f715fab053374d808c90dSteve Block//       copyright notice, this list of conditions and the following
1044f0eee88ff00398ff7f715fab053374d808c90dSteve Block//       disclaimer in the documentation and/or other materials provided
1144f0eee88ff00398ff7f715fab053374d808c90dSteve Block//       with the distribution.
1244f0eee88ff00398ff7f715fab053374d808c90dSteve Block//     * Neither the name of Google Inc. nor the names of its
1344f0eee88ff00398ff7f715fab053374d808c90dSteve Block//       contributors may be used to endorse or promote products derived
1444f0eee88ff00398ff7f715fab053374d808c90dSteve Block//       from this software without specific prior written permission.
1544f0eee88ff00398ff7f715fab053374d808c90dSteve Block//
1644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include <stdlib.h>
2944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "v8.h"
3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "ast.h"
3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "bootstrapper.h"
3444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "codegen.h"
3544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "compilation-cache.h"
3644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "debug.h"
3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "deoptimizer.h"
3844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "heap-profiler.h"
3944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "hydrogen.h"
4044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "isolate.h"
4144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "lithium-allocator.h"
4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "log.h"
43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "messages.h"
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "platform.h"
4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "regexp-stack.h"
4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "runtime-profiler.h"
4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "scopeinfo.h"
4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "serialize.h"
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "simulator.h"
5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "spaces.h"
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "stub-cache.h"
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "version.h"
53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "vm-state-inl.h"
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5644f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace v8 {
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal {
5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
598b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochAtomic32 ThreadId::highest_thread_id_ = 0;
608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochint ThreadId::AllocateThreadId() {
628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return new_id;
648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochint ThreadId::GetCurrentThreadId() {
6885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (thread_id == 0) {
708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    thread_id = AllocateThreadId();
7185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return thread_id;
748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
766d7cb000ed533f52d745e60663019ff891bb19a8Ben Murdoch
77257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochThreadLocalTop::ThreadLocalTop() {
78257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  InitializeInternal();
7969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // This flag may be set using v8::V8::IgnoreOutOfMemoryException()
8069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // before an isolate is initialized. The initialize methods below do
8169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // not touch it to preserve its value.
8269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  ignore_out_of_memory_ = false;
83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid ThreadLocalTop::InitializeInternal() {
87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  c_entry_fp_ = 0;
88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  handler_ = 0;
89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef USE_SIMULATOR
90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  simulator_ = NULL;
91257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  js_entry_sp_ = NULL;
93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  external_callback_ = NULL;
94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  current_vm_state_ = EXTERNAL;
95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  try_catch_handler_address_ = NULL;
96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  context_ = NULL;
97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_id_ = ThreadId::Invalid();
98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  external_caught_exception_ = false;
99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  failed_access_check_callback_ = NULL;
100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  save_context_ = NULL;
101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  catcher_ = NULL;
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  top_lookup_result_ = NULL;
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // These members are re-initialized later after deserialization
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is complete.
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pending_exception_ = NULL;
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  has_pending_message_ = false;
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pending_message_obj_ = NULL;
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pending_message_script_ = NULL;
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scheduled_exception_ = NULL;
111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid ThreadLocalTop::Initialize() {
115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  InitializeInternal();
116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef USE_SIMULATOR
117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef V8_TARGET_ARCH_ARM
118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  simulator_ = Simulator::current(isolate_);
119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#elif V8_TARGET_ARCH_MIPS
120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  simulator_ = Simulator::current(isolate_);
121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_id_ = ThreadId::Current();
124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochv8::TryCatch* ThreadLocalTop::TryCatchHandler() {
128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address());
129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Create a dummy thread that will wait forever on a semaphore. The only
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// purpose for this thread is to have some stack area to save essential data
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// into for use by a stacks only core dump (aka minidump).
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass PreallocatedMemoryThread: public Thread {
13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* data() {
13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (data_ready_semaphore_ != NULL) {
13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      // Initial access is guarded until the data has been published.
14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      data_ready_semaphore_->Wait();
14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      delete data_ready_semaphore_;
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      data_ready_semaphore_ = NULL;
14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return data_;
14544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
14644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unsigned length() {
14844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (data_ready_semaphore_ != NULL) {
14944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      // Initial access is guarded until the data has been published.
15044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      data_ready_semaphore_->Wait();
15144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      delete data_ready_semaphore_;
15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      data_ready_semaphore_ = NULL;
15344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
15444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return length_;
15544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
15644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
15744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Stop the PreallocatedMemoryThread and release its resources.
15844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void StopThread() {
15944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    keep_running_ = false;
16044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    wait_for_ever_semaphore_->Signal();
16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
16244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Wait for the thread to terminate.
16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Join();
16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (data_ready_semaphore_ != NULL) {
16644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      delete data_ready_semaphore_;
16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      data_ready_semaphore_ = NULL;
16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
17044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    delete wait_for_ever_semaphore_;
17144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    wait_for_ever_semaphore_ = NULL;
17244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
17344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
17444f0eee88ff00398ff7f715fab053374d808c90dSteve Block protected:
17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // When the thread starts running it will allocate a fixed number of bytes
17644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // on the stack and publish the location of this memory for others to use.
17744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Run() {
17844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EmbeddedVector<char, 15 * 1024> local_buffer;
17944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Initialize the buffer with a known good value.
18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
18244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                local_buffer.length());
18344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Publish the local buffer and signal its availability.
18544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    data_ = local_buffer.start();
18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    length_ = local_buffer.length();
18744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    data_ready_semaphore_->Signal();
18844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
18944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    while (keep_running_) {
19044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      // This thread will wait here until the end of time.
19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      wait_for_ever_semaphore_->Wait();
19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
19344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
19444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Make sure we access the buffer after the wait to remove all possibility
19544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // of it being optimized away.
19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                local_buffer.length());
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
2023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PreallocatedMemoryThread()
2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : Thread("v8:PreallocMem"),
20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        keep_running_(true),
20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        data_ready_semaphore_(OS::CreateSemaphore(0)),
20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        data_(NULL),
20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        length_(0) {
20944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Used to make sure that the thread keeps looping even for spurious wakeups.
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool keep_running_;
21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // This semaphore is used by the PreallocatedMemoryThread to wait for ever.
21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Semaphore* wait_for_ever_semaphore_;
21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Semaphore to signal that the data has been initialized.
21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Semaphore* data_ready_semaphore_;
21844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
21944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Location and size of the preallocated memory block.
22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* data_;
22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  unsigned length_;
22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
22344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class Isolate;
22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
22544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread);
22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
22744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
22844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
22944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::PreallocatedMemoryThreadStart() {
23044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (preallocated_memory_thread_ != NULL) return;
2313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  preallocated_memory_thread_ = new PreallocatedMemoryThread();
23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  preallocated_memory_thread_->Start();
23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
23644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::PreallocatedMemoryThreadStop() {
23744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (preallocated_memory_thread_ == NULL) return;
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  preallocated_memory_thread_->StopThread();
23944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Done with the thread entirely.
24044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete preallocated_memory_thread_;
24144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  preallocated_memory_thread_ = NULL;
24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
24544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::PreallocatedStorageInit(size_t size) {
24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(free_list_.next_ == &free_list_);
24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(free_list_.previous_ == &free_list_);
24844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PreallocatedStorage* free_chunk =
24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<PreallocatedStorage*>(new char[size]);
25044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  free_list_.next_ = free_list_.previous_ = free_chunk;
25144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  free_chunk->next_ = free_chunk->previous_ = &free_list_;
25244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  free_chunk->size_ = size - sizeof(PreallocatedStorage);
25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  preallocated_storage_preallocated_ = true;
25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
25744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid* Isolate::PreallocatedStorageNew(size_t size) {
25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!preallocated_storage_preallocated_) {
25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return FreeStoreAllocationPolicy::New(size);
26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
26144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(free_list_.next_ != &free_list_);
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(free_list_.previous_ != &free_list_);
26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
26444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  size = (size + kPointerSize - 1) & ~(kPointerSize - 1);
26544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Search for exact fit.
26644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  for (PreallocatedStorage* storage = free_list_.next_;
26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block       storage != &free_list_;
26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block       storage = storage->next_) {
26944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (storage->size_ == size) {
27044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      storage->Unlink();
27144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      storage->LinkTo(&in_use_list_);
27244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return reinterpret_cast<void*>(storage + 1);
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Search for first fit.
27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  for (PreallocatedStorage* storage = free_list_.next_;
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block       storage != &free_list_;
27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block       storage = storage->next_) {
27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (storage->size_ >= size + sizeof(PreallocatedStorage)) {
28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      storage->Unlink();
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      storage->LinkTo(&in_use_list_);
28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      PreallocatedStorage* left_over =
28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block          reinterpret_cast<PreallocatedStorage*>(
28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block              reinterpret_cast<char*>(storage + 1) + size);
28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage);
28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) ==
28744f0eee88ff00398ff7f715fab053374d808c90dSteve Block             storage->size_);
28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      storage->size_ = size;
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      left_over->LinkTo(&free_list_);
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return reinterpret_cast<void*>(storage + 1);
29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Allocation failure.
29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(false);
29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return NULL;
29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// We don't attempt to coalesce.
30044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::PreallocatedStorageDelete(void* p) {
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (p == NULL) {
30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return;
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!preallocated_storage_preallocated_) {
30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    FreeStoreAllocationPolicy::Delete(p);
30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return;
30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1;
30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(storage->next_->previous_ == storage);
31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(storage->previous_->next_ == storage);
31144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  storage->Unlink();
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  storage->LinkTo(&free_list_);
31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31585b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochIsolate* Isolate::default_isolate_ = NULL;
31685b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochThread::LocalStorageKey Isolate::isolate_key_;
31785b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochThread::LocalStorageKey Isolate::thread_id_key_;
31885b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochThread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
31985b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochMutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
32085b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochIsolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
32185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
32285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
32344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ThreadId thread_id) {
3258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ASSERT(!thread_id.Equals(ThreadId::Invalid()));
32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  {
32885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    ScopedLock lock(process_wide_mutex_);
32985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL);
33085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    thread_data_table_->Insert(per_thread);
33185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return per_thread;
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
33744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate::PerIsolateThreadData*
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate::FindOrAllocatePerThreadDataForThisThread() {
3398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ThreadId thread_id = ThreadId::Current();
34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* per_thread = NULL;
34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  {
34285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    ScopedLock lock(process_wide_mutex_);
34385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    per_thread = thread_data_table_->Lookup(this, thread_id);
34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (per_thread == NULL) {
34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      per_thread = AllocatePerIsolateThreadData(thread_id);
34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return per_thread;
34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochIsolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() {
353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ThreadId thread_id = ThreadId::Current();
354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  PerIsolateThreadData* per_thread = NULL;
355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  {
35685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    ScopedLock lock(process_wide_mutex_);
35785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    per_thread = thread_data_table_->Lookup(this, thread_id);
358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return per_thread;
360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
36344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::EnsureDefaultIsolate() {
36485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  ScopedLock lock(process_wide_mutex_);
36585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  if (default_isolate_ == NULL) {
36685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    isolate_key_ = Thread::CreateThreadLocalKey();
36785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    thread_id_key_ = Thread::CreateThreadLocalKey();
36885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
36985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    thread_data_table_ = new Isolate::ThreadDataTable();
37085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    default_isolate_ = new Isolate();
37185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  }
37244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // because a non-null thread data may be already set.
37485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  if (Thread::GetThreadLocal(isolate_key_) == NULL) {
37585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    Thread::SetThreadLocal(isolate_key_, default_isolate_);
376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstruct StaticInitializer {
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StaticInitializer() {
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Isolate::EnsureDefaultIsolate();
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} static_initializer;
38444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
38644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockDebugger* Isolate::GetDefaultIsolateDebugger() {
38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EnsureDefaultIsolate();
38885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return default_isolate_->debugger();
38944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
39344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockStackGuard* Isolate::GetDefaultIsolateStackGuard() {
39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EnsureDefaultIsolate();
39585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return default_isolate_->stack_guard();
39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::EnterDefaultIsolate() {
40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EnsureDefaultIsolate();
40185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  ASSERT(default_isolate_ != NULL);
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* data = CurrentPerIsolateThreadData();
40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // If not yet in default isolate - enter it.
40585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  if (data == NULL || data->isolate() != default_isolate_) {
40685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    default_isolate_->Enter();
40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate* Isolate::GetDefaultIsolateForLocking() {
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EnsureDefaultIsolate();
41385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return default_isolate_;
41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochAddress Isolate::get_address_from_id(Isolate::AddressId id) {
418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return isolate_addresses_[id];
419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochchar* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) {
423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Iterate(v, thread);
425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return thread_storage + sizeof(ThreadLocalTop);
426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::IterateThread(ThreadVisitor* v) {
430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v->VisitThread(this, thread_local_top());
431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::IterateThread(ThreadVisitor* v, char* t) {
435257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
436257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v->VisitThread(this, thread);
437257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
438257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
440257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Visit the roots from the top for a given thread.
442257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* pending;
443257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The pending exception can sometimes be a failure.  We can't show
444257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // that to the GC, which only understands objects.
445257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (thread->pending_exception_->ToObject(&pending)) {
446257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v->VisitPointer(&pending);
447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    thread->pending_exception_ = pending;  // In case GC updated it.
448257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v->VisitPointer(&(thread->pending_message_obj_));
450257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v->VisitPointer(BitCast<Object**>(&(thread->pending_message_script_)));
451257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v->VisitPointer(BitCast<Object**>(&(thread->context_)));
452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* scheduled;
453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (thread->scheduled_exception_->ToObject(&scheduled)) {
454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v->VisitPointer(&scheduled);
455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    thread->scheduled_exception_ = scheduled;
456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (v8::TryCatch* block = thread->TryCatchHandler();
459257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch       block != NULL;
460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch       block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v->VisitPointer(BitCast<Object**>(&(block->exception_)));
462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v->VisitPointer(BitCast<Object**>(&(block->message_)));
463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Iterate over pointers on native execution stack.
466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    it.frame()->Iterate(v);
468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Iterate pointers in live lookup results.
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  thread->top_lookup_result_->Iterate(v);
472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::Iterate(ObjectVisitor* v) {
476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ThreadLocalTop* current_t = thread_local_top();
477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Iterate(v, current_t);
478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The ARM simulator has a separate JS stack.  We therefore register
483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // the C++ try catch handler with the simulator and get back an
484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // address that can be used for comparisons with addresses into the
485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // JS stack.  When running without the simulator, the address
486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // returned will be the address of the C++ try catch handler itself.
487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Address address = reinterpret_cast<Address>(
488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->set_try_catch_handler_address(address);
490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(thread_local_top()->TryCatchHandler() == that);
495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->set_try_catch_handler_address(
496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      reinterpret_cast<Address>(that->next_));
497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->catcher_ = NULL;
498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SimulatorStack::UnregisterCTryCatch();
499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<String> Isolate::StackTraceString() {
503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (stack_trace_nesting_level_ == 0) {
504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    stack_trace_nesting_level_++;
505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HeapStringAllocator allocator;
506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StringStream::ClearMentionedObjectCache();
507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StringStream accumulator(&allocator);
508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    incomplete_message_ = &accumulator;
509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    PrintStack(&accumulator);
510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<String> stack_trace = accumulator.ToString();
511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    incomplete_message_ = NULL;
512257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    stack_trace_nesting_level_ = 0;
513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return stack_trace;
514257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (stack_trace_nesting_level_ == 1) {
515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    stack_trace_nesting_level_++;
516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    OS::PrintError(
517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "\n\nAttempt to print stack while printing stack (double fault)\n");
518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    OS::PrintError(
519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "If you are lucky you may find a partial stack dump on stdout.\n\n");
520257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    incomplete_message_->OutputToStdOut();
521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return factory()->empty_symbol();
522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    OS::Abort();
524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Unreachable
525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return factory()->empty_symbol();
526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Isolate::CaptureAndSetCurrentStackTraceFor(Handle<JSObject> error_object) {
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (capture_stack_trace_for_uncaught_exceptions_) {
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Capture stack trace for a detailed exception message.
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<String> key = factory()->hidden_stack_trace_symbol();
5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        stack_trace_for_uncaught_exceptions_frame_limit_,
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        stack_trace_for_uncaught_exceptions_options_);
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JSObject::SetHiddenProperty(error_object, key, stack_trace);
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
542257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<JSArray> Isolate::CaptureCurrentStackTrace(
543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int frame_limit, StackTrace::StackTraceOptions options) {
544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Ensure no negative values.
545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int limit = Max(frame_limit, 0);
546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
547257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> column_key = factory()->LookupAsciiSymbol("column");
549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> line_key = factory()->LookupAsciiSymbol("lineNumber");
550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> script_key = factory()->LookupAsciiSymbol("scriptName");
551257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> name_or_source_url_key =
552257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      factory()->LookupAsciiSymbol("nameOrSourceURL");
553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> script_name_or_source_url_key =
554257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      factory()->LookupAsciiSymbol("scriptNameOrSourceURL");
555257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> function_key = factory()->LookupAsciiSymbol("functionName");
556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> eval_key = factory()->LookupAsciiSymbol("isEval");
557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> constructor_key =
558257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      factory()->LookupAsciiSymbol("isConstructor");
559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
560257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StackTraceFrameIterator it(this);
561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int frames_seen = 0;
562257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  while (!it.done() && (frames_seen < limit)) {
563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JavaScriptFrame* frame = it.frame();
564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Set initial size to the maximum inlining level + 1 for the outermost
565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // function.
566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    List<FrameSummary> frames(Compiler::kMaxInliningLevels + 1);
567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    frame->Summarize(&frames);
568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Create a JSObject to hold the information for the StackFrame.
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<JSFunction> fun = frames[i].function();
573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<Script> script(Script::cast(fun->shared()->script()));
574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (options & StackTrace::kLineNumber) {
576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        int script_line_offset = script->line_offset()->value();
577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        int position = frames[i].code()->SourcePosition(frames[i].pc());
578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        int line_number = GetScriptLineNumber(script, position);
579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        // line_number is already shifted by the script_line_offset.
580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        int relative_line_number = line_number - script_line_offset;
581257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          int start = (relative_line_number == 0) ? 0 :
584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          int column_offset = position - start;
586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          if (relative_line_number == 0) {
587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            // For the case where the code is on the same line as the script
588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            // tag.
589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            column_offset += script->column_offset()->value();
590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          }
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CHECK_NOT_EMPTY_HANDLE(
5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              this,
5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              JSObject::SetLocalPropertyIgnoreAttributes(
5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  stack_frame, column_key,
5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE));
596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CHECK_NOT_EMPTY_HANDLE(
5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            this,
5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            JSObject::SetLocalPropertyIgnoreAttributes(
6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                stack_frame, line_key,
6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                Handle<Smi>(Smi::FromInt(line_number + 1)), NONE));
602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (options & StackTrace::kScriptName) {
605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> script_name(script->name(), this);
6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CHECK_NOT_EMPTY_HANDLE(this,
6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               JSObject::SetLocalPropertyIgnoreAttributes(
6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   stack_frame, script_key, script_name, NONE));
609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (options & StackTrace::kScriptNameOrSourceURL) {
612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> script_name(script->name(), this);
613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<JSValue> script_wrapper = GetScriptWrapper(script);
614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> property = GetProperty(script_wrapper,
615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                              name_or_source_url_key);
616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        ASSERT(property->IsJSFunction());
617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<JSFunction> method = Handle<JSFunction>::cast(property);
618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        bool caught_exception;
619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                   NULL, &caught_exception);
621257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (caught_exception) {
622257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = factory()->undefined_value();
623257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CHECK_NOT_EMPTY_HANDLE(this,
6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               JSObject::SetLocalPropertyIgnoreAttributes(
6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   stack_frame, script_name_or_source_url_key,
6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   result, NONE));
628257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
629257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
630257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (options & StackTrace::kFunctionName) {
631257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> fun_name(fun->shared()->name(), this);
632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (fun_name->ToBoolean()->IsFalse()) {
633257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
634257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CHECK_NOT_EMPTY_HANDLE(this,
6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               JSObject::SetLocalPropertyIgnoreAttributes(
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   stack_frame, function_key, fun_name, NONE));
638257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
639257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
640257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (options & StackTrace::kIsEval) {
641257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        int type = Smi::cast(script->compilation_type())->value();
642257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
643257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            factory()->true_value() : factory()->false_value();
6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CHECK_NOT_EMPTY_HANDLE(this,
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               JSObject::SetLocalPropertyIgnoreAttributes(
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   stack_frame, eval_key, is_eval, NONE));
647257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
648257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
649257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (options & StackTrace::kIsConstructor) {
650257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> is_constructor = (frames[i].is_constructor()) ?
651257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            factory()->true_value() : factory()->false_value();
6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CHECK_NOT_EMPTY_HANDLE(this,
6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               JSObject::SetLocalPropertyIgnoreAttributes(
6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   stack_frame, constructor_key,
6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   is_constructor, NONE));
656257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
657257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
659257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      frames_seen++;
660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    it.Advance();
662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
663257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
664257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stack_trace->set_length(Smi::FromInt(frames_seen));
665257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return stack_trace;
666257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
667257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
668257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
669257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::PrintStack() {
670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (stack_trace_nesting_level_ == 0) {
671257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    stack_trace_nesting_level_++;
672257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
673257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StringAllocator* allocator;
674257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (preallocated_message_space_ == NULL) {
675257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      allocator = new HeapStringAllocator();
676257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else {
677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      allocator = preallocated_message_space_;
678257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
679257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StringStream::ClearMentionedObjectCache();
681257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StringStream accumulator(allocator);
682257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    incomplete_message_ = &accumulator;
683257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    PrintStack(&accumulator);
684257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    accumulator.OutputToStdOut();
68569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    InitializeLoggingAndCounters();
686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    accumulator.Log();
687257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    incomplete_message_ = NULL;
688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    stack_trace_nesting_level_ = 0;
689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (preallocated_message_space_ == NULL) {
690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Remove the HeapStringAllocator created above.
691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      delete allocator;
692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
693257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (stack_trace_nesting_level_ == 1) {
694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    stack_trace_nesting_level_++;
695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    OS::PrintError(
696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "\n\nAttempt to print stack while printing stack (double fault)\n");
697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    OS::PrintError(
698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "If you are lucky you may find a partial stack dump on stdout.\n\n");
699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    incomplete_message_->OutputToStdOut();
700257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
701257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
702257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void PrintFrames(StringStream* accumulator,
705257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        StackFrame::PrintMode mode) {
706257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StackFrameIterator it;
707257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; !it.done(); it.Advance()) {
708257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    it.frame()->Print(accumulator, mode, i++);
709257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
710257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
711257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
712257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
713257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::PrintStack(StringStream* accumulator) {
714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!IsInitialized()) {
715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    accumulator->Add(
716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        "\n==== Stack trace is not available ==========================\n\n");
717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    accumulator->Add(
718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        "\n==== Isolate for the thread is not initialized =============\n\n");
719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return;
720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The MentionedObjectCache is not GC-proof at the moment.
722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  AssertNoAllocation nogc;
723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(StringStream::IsMentionedObjectCacheClear());
724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Avoid printing anything if there are no frames.
726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (c_entry_fp(thread_local_top()) == 0) return;
727257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
728257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  accumulator->Add(
729257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "\n==== Stack trace ============================================\n\n");
730257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  PrintFrames(accumulator, StackFrame::OVERVIEW);
731257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  accumulator->Add(
733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "\n==== Details ================================================\n\n");
734257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  PrintFrames(accumulator, StackFrame::DETAILS);
735257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  accumulator->PrintMentionedObjectCache();
737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  accumulator->Add("=====================\n\n");
738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
739257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::SetFailedAccessCheckCallback(
742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::FailedAccessCheckCallback callback) {
743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->failed_access_check_callback_ = callback;
744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
745257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) {
748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!thread_local_top()->failed_access_check_callback_) return;
749257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(receiver->IsAccessCheckNeeded());
751257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(context());
752257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
753257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Get the data object from access check info.
754257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!constructor->shared()->IsApiFunction()) return;
756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* data_obj =
757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      constructor->shared()->get_api_func_data()->access_check_info();
758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (data_obj == heap_.undefined_value()) return;
759257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
760257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HandleScope scope;
761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<JSObject> receiver_handle(receiver);
762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  { VMState state(this, EXTERNAL);
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    thread_local_top()->failed_access_check_callback_(
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      v8::Utils::ToLocal(receiver_handle),
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      type,
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      v8::Utils::ToLocal(data));
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
769257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
771257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
772257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochenum MayAccessDecision {
773257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  YES, NO, UNKNOWN
774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
775257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic MayAccessDecision MayAccessPreCheck(Isolate* isolate,
778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                           JSObject* receiver,
779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                           v8::AccessType type) {
780257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // During bootstrapping, callback functions are not enabled yet.
781257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (isolate->bootstrapper()->IsActive()) return YES;
782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (receiver->IsJSGlobalProxy()) {
784257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Object* receiver_context = JSGlobalProxy::cast(receiver)->context();
785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!receiver_context->IsContext()) return NO;
786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Get the global context of current top context.
788257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // avoid using Isolate::global_context() because it uses Handle.
789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Context* global_context = isolate->context()->global()->global_context();
790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (receiver_context == global_context) return YES;
791257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
792257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (Context::cast(receiver_context)->security_token() ==
793257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        global_context->security_token())
794257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return YES;
795257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
796257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
797257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return UNKNOWN;
798257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
801257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                             v8::AccessType type) {
803257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(receiver->IsAccessCheckNeeded());
804257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
805257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The callers of this method are not expecting a GC.
806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  AssertNoAllocation no_gc;
807257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
808257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Skip checks for hidden properties access.  Note, we do not
809257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // require existence of a context in this case.
810257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (key == heap_.hidden_symbol()) return true;
811257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
812257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check for compatibility between the security tokens in the
813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // current lexical context and the accessed object.
814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(context());
815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
816257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
817257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (decision != UNKNOWN) return decision == YES;
818257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Get named access check callback
820257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
821257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!constructor->shared()->IsApiFunction()) return false;
822257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* data_obj =
824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch     constructor->shared()->get_api_func_data()->access_check_info();
825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (data_obj == heap_.undefined_value()) return false;
826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
828257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::NamedSecurityCallback callback =
829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!callback) return false;
832257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
833257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HandleScope scope(this);
834257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<JSObject> receiver_handle(receiver, this);
835257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<Object> key_handle(key, this);
836257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOG(this, ApiNamedSecurityCheck(key));
838257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool result = false;
839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  {
840257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Leaving JavaScript.
841257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    VMState state(this, EXTERNAL);
842257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    result = callback(v8::Utils::ToLocal(receiver_handle),
843257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      v8::Utils::ToLocal(key_handle),
844257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      type,
845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      v8::Utils::ToLocal(data));
846257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return result;
848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Isolate::MayIndexedAccess(JSObject* receiver,
852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               uint32_t index,
853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               v8::AccessType type) {
854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(receiver->IsAccessCheckNeeded());
855257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check for compatibility between the security tokens in the
856257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // current lexical context and the accessed object.
857257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(context());
858257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
860257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (decision != UNKNOWN) return decision == YES;
861257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
862257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Get indexed access check callback
863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
864257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!constructor->shared()->IsApiFunction()) return false;
865257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
866257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* data_obj =
867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      constructor->shared()->get_api_func_data()->access_check_info();
868257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (data_obj == heap_.undefined_value()) return false;
869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
871257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::IndexedSecurityCallback callback =
872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!callback) return false;
875257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
876257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HandleScope scope(this);
877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<JSObject> receiver_handle(receiver, this);
878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
879257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOG(this, ApiIndexedSecurityCheck(index));
880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool result = false;
881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  {
882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Leaving JavaScript.
883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    VMState state(this, EXTERNAL);
884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    result = callback(v8::Utils::ToLocal(receiver_handle),
885257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      index,
886257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      type,
887257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      v8::Utils::ToLocal(data));
888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return result;
890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
891257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
892257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
893257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochconst char* const Isolate::kStackOverflowMessage =
894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  "Uncaught RangeError: Maximum call stack size exceeded";
895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
897257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochFailure* Isolate::StackOverflow() {
898257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HandleScope scope;
899257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<String> key = factory()->stack_overflow_symbol();
900257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<JSObject> boilerplate =
901257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<JSObject>::cast(GetProperty(js_builtins_object(), key));
902257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<Object> exception = Copy(boilerplate);
903257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // TODO(1240995): To avoid having to call JavaScript code to compute
904257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // the message for stack overflow exceptions which is very likely to
905257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // double fault with another stack overflow exception, we use a
906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // precomputed message.
907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DoThrow(*exception, NULL);
908257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Failure::Exception();
909257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochFailure* Isolate::TerminateExecution() {
913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DoThrow(heap_.termination_exception(), NULL);
914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Failure::Exception();
915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochFailure* Isolate::Throw(Object* exception, MessageLocation* location) {
919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DoThrow(exception, location);
920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Failure::Exception();
921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
922257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
923257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
924257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochFailure* Isolate::ReThrow(MaybeObject* exception, MessageLocation* location) {
925257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool can_be_caught_externally = false;
926257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool catchable_by_javascript = is_catchable_by_javascript(exception);
927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->catcher_ = can_be_caught_externally ?
930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      try_catch_handler() : NULL;
931257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
932257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Set the exception being re-thrown.
933257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  set_pending_exception(exception);
934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (exception->IsFailure()) return exception->ToFailureUnchecked();
935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Failure::Exception();
936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochFailure* Isolate::ThrowIllegalOperation() {
940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Throw(heap_.illegal_access_symbol());
941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::ScheduleThrow(Object* exception) {
945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // When scheduling a throw we first throw the exception to get the
946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // error reporting if it is uncaught before rescheduling it.
947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Throw(exception);
948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->scheduled_exception_ = pending_exception();
949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->external_caught_exception_ = false;
950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  clear_pending_exception();
951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochFailure* Isolate::PromoteScheduledException() {
955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MaybeObject* thrown = scheduled_exception();
956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  clear_scheduled_exception();
957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Re-throw the exception to avoid getting repeated error reporting.
958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return ReThrow(thrown);
959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
960257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
961257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
962257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::PrintCurrentStackTrace(FILE* out) {
963257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StackTraceFrameIterator it(this);
964257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  while (!it.done()) {
965257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HandleScope scope;
966257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Find code position if recorded in relocation info.
967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JavaScriptFrame* frame = it.frame();
968257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int pos = frame->LookupCode()->SourcePosition(frame->pc());
969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<Object> pos_obj(Smi::FromInt(pos));
970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Fetch function and receiver.
971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<JSFunction> fun(JSFunction::cast(frame->function()));
972257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<Object> recv(frame->receiver());
973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Advance to the next JavaScript frame and determine if the
974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // current frame is the top-level frame.
975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    it.Advance();
976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<Object> is_top_level = it.done()
977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        ? factory()->true_value()
978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        : factory()->false_value();
979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Generate and print stack trace line.
980257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<String> line =
981257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (line->length() > 0) {
983257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      line->PrintOn(out);
984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      fprintf(out, "\n");
985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::ComputeLocation(MessageLocation* target) {
991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StackTraceFrameIterator it(this);
993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!it.done()) {
994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JavaScriptFrame* frame = it.frame();
995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JSFunction* fun = JSFunction::cast(frame->function());
996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Object* script = fun->shared()->script();
997257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (script->IsScript() &&
998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        !(Script::cast(script)->source()->IsUndefined())) {
999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      int pos = frame->LookupCode()->SourcePosition(frame->pc());
1000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Compute the location from the function and the reloc info.
1001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<Script> casted_script(Script::cast(script));
1002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      *target = MessageLocation(casted_script, pos, pos + 1);
1003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1004257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1005257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1006257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1008257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Isolate::ShouldReportException(bool* can_be_caught_externally,
1009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    bool catchable_by_javascript) {
1010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Find the top-most try-catch handler.
1011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StackHandler* handler =
1012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StackHandler::FromAddress(Isolate::handler(thread_local_top()));
10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (handler != NULL && !handler->is_catch()) {
1014257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    handler = handler->next();
1015257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1016257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1017257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Get the address of the external handler so we can compare the address to
1018257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // determine which one is closer to the top of the stack.
1019257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Address external_handler_address =
1020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread_local_top()->try_catch_handler_address();
1021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1022257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The exception has been externally caught if and only if there is
1023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // an external handler which is on top of the top-most try-catch
1024257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // handler.
1025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  *can_be_caught_externally = external_handler_address != NULL &&
1026257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      (handler == NULL || handler->address() > external_handler_address ||
1027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch       !catchable_by_javascript);
1028257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1029257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (*can_be_caught_externally) {
1030257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Only report the exception if the external handler is verbose.
1031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return try_catch_handler()->is_verbose_;
1032257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Report the exception if it isn't caught by JavaScript code.
1034257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return handler == NULL;
1035257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1036257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1037257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Isolate::IsErrorObject(Handle<Object> obj) {
10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!obj->IsJSObject()) return false;
10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* error_key = *(factory()->LookupAsciiSymbol("$Error"));
10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* error_constructor =
10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (Object* prototype = *obj; !prototype->IsNull();
10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       prototype = prototype->GetPrototype()) {
10483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!prototype->IsJSObject()) return false;
10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return true;
10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return false;
10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Isolate::DoThrow(Object* exception, MessageLocation* location) {
1058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(!has_pending_exception());
1059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HandleScope scope;
10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> exception_handle(exception);
1062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1063257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Determine reporting and whether the exception is caught externally.
1064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool catchable_by_javascript = is_catchable_by_javascript(exception);
1065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool can_be_caught_externally = false;
1066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool should_report_exception =
1067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
1068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool report_exception = catchable_by_javascript && should_report_exception;
10693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool try_catch_needs_message =
10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      can_be_caught_externally && try_catch_handler()->capture_message_;
10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool bootstrapping = bootstrapper()->IsActive();
1072257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1073257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
1074257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Notify debugger of exception.
1075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (catchable_by_javascript) {
1076257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    debugger_->OnException(exception_handle, report_exception);
1077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
1079257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Generate the message if required.
1081257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (report_exception || try_catch_needs_message) {
10823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MessageLocation potential_computed_location;
1083257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (location == NULL) {
10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // If no location was specified we use a computed one instead.
1085257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      ComputeLocation(&potential_computed_location);
1086257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      location = &potential_computed_location;
1087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // It's not safe to try to make message objects or collect stack traces
10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // while the bootstrapper is active since the infrastructure may not have
10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // been properly initialized.
10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!bootstrapping) {
1092257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<String> stack_trace;
1093257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (FLAG_trace_exception) stack_trace = StackTraceString();
1094257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<JSArray> stack_trace_object;
10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (capture_stack_trace_for_uncaught_exceptions_) {
10963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (IsErrorObject(exception_handle)) {
10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // We fetch the stack trace that corresponds to this error object.
10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          String* key = heap()->hidden_stack_trace_symbol();
10993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          Object* stack_property =
11003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              JSObject::cast(*exception_handle)->GetHiddenProperty(key);
11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Property lookup may have failed.  In this case it's probably not
11023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // a valid Error object.
11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          if (stack_property->IsJSArray()) {
11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          }
11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (stack_trace_object.is_null()) {
11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Not an error object, we capture at throw site.
1109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          stack_trace_object = CaptureCurrentStackTrace(
1110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              stack_trace_for_uncaught_exceptions_frame_limit_,
1111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              stack_trace_for_uncaught_exceptions_options_);
11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
1113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<Object> message_obj = MessageHandler::MakeMessageObject(
11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          "uncaught_exception",
11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          location,
11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          HandleVector<Object>(&exception_handle, 1),
11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          stack_trace,
1119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          stack_trace_object);
11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      thread_local_top()->pending_message_obj_ = *message_obj;
11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (location != NULL) {
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        thread_local_top()->pending_message_script_ = *location->script();
11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        thread_local_top()->pending_message_start_pos_ = location->start_pos();
11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        thread_local_top()->pending_message_end_pos_ = location->end_pos();
11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else if (location != NULL && !location->script().is_null()) {
11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // We are bootstrapping and caught an error where the location is set
11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // and we have a script for the location.
11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // In this case we could have an extension (or an internal error
11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // somewhere) and we print out the line number at which the error occured
11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // to the console for easier debugging.
11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int line_number = GetScriptLineNumberSafe(location->script(),
11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                location->start_pos());
11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      OS::PrintError("Extension or internal compilation error at line %d.\n",
11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     line_number);
1136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Save the message for reporting if the the exception remains uncaught.
1140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->has_pending_message_ = report_exception;
1141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Do not forget to clean catcher_ if currently thrown exception cannot
1143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // be caught.  If necessary, ReThrow will update the catcher.
1144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->catcher_ = can_be_caught_externally ?
1145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      try_catch_handler() : NULL;
1146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
11473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  set_pending_exception(*exception_handle);
1148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Isolate::IsExternallyCaught() {
1152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(has_pending_exception());
1153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if ((thread_local_top()->catcher_ == NULL) ||
1155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      (try_catch_handler() != thread_local_top()->catcher_)) {
1156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // When throwing the exception, we found no v8::TryCatch
1157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // which should care about this exception.
1158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return false;
1159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!is_catchable_by_javascript(pending_exception())) {
1162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return true;
1163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1164257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Get the address of the external handler so we can compare the address to
1166257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // determine which one is closer to the top of the stack.
1167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Address external_handler_address =
1168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread_local_top()->try_catch_handler_address();
1169257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(external_handler_address != NULL);
1170257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The exception has been externally caught if and only if there is
1172257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // an external handler which is on top of the top-most try-finally
1173257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // handler.
1174257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // There should be no try-catch blocks as they would prohibit us from
1175257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // finding external catcher in the first place (see catcher_ check above).
1176257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  //
1177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Note, that finally clause would rethrow an exception unless it's
1178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // aborted by jumps in control flow like return, break, etc. and we'll
1179257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // have another chances to set proper v8::TryCatch.
1180257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StackHandler* handler =
1181257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1182257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  while (handler != NULL && handler->address() < external_handler_address) {
11833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(!handler->is_catch());
11843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (handler->is_finally()) return false;
1185257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    handler = handler->next();
1187257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1188257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return true;
1190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1192257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1193257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::ReportPendingMessages() {
1194257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(has_pending_exception());
1195257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  PropagatePendingExceptionToExternalTryCatch();
1196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1197257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If the pending exception is OutOfMemoryException set out_of_memory in
1198257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // the global context.  Note: We have to mark the global context here
1199257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
1200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // set it.
1201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HandleScope scope;
1202257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
1203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    context()->mark_out_of_memory();
1204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (thread_local_top_.pending_exception_ ==
1205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             heap()->termination_exception()) {
1206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Do nothing: if needed, the exception has been already propagated to
1207257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // v8::TryCatch.
1208257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1209257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (thread_local_top_.has_pending_message_) {
1210257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread_local_top_.has_pending_message_ = false;
1211257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
1212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        HandleScope scope;
1213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Handle<Object> message_obj(thread_local_top_.pending_message_obj_);
1214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (thread_local_top_.pending_message_script_ != NULL) {
1215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          Handle<Script> script(thread_local_top_.pending_message_script_);
1216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          int start_pos = thread_local_top_.pending_message_start_pos_;
1217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          int end_pos = thread_local_top_.pending_message_end_pos_;
1218257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          MessageLocation location(script, start_pos, end_pos);
1219257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          MessageHandler::ReportMessage(this, &location, message_obj);
1220257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        } else {
1221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          MessageHandler::ReportMessage(this, NULL, message_obj);
1222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
1223257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
1224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  clear_pending_message();
1227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::TraceException(bool flag) {
1231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  FLAG_trace_exception = flag;  // TODO(isolates): This is an unfortunate use.
1232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Isolate::OptionalRescheduleException(bool is_bottom_call) {
1236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(has_pending_exception());
1237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  PropagatePendingExceptionToExternalTryCatch();
1238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
12393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Always reschedule out of memory exceptions.
1240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!is_out_of_memory()) {
1241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bool is_termination_exception =
1242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        pending_exception() == heap_.termination_exception();
1243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Do not reschedule the exception if this is the bottom call.
1245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bool clear_exception = is_bottom_call;
1246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1247257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (is_termination_exception) {
1248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (is_bottom_call) {
1249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        thread_local_top()->external_caught_exception_ = false;
1250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        clear_pending_exception();
1251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        return false;
1252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
1253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else if (thread_local_top()->external_caught_exception_) {
1254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // If the exception is externally caught, clear it if there are no
1255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // JavaScript frames on the way to the C++ frame that has the
1256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // external handler.
1257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      ASSERT(thread_local_top()->try_catch_handler_address() != NULL);
1258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Address external_handler_address =
1259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          thread_local_top()->try_catch_handler_address();
1260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      JavaScriptFrameIterator it;
1261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (it.done() || (it.frame()->sp() > external_handler_address)) {
1262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        clear_exception = true;
1263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
1264257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1265257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1266257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Clear the exception if needed.
1267257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (clear_exception) {
1268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread_local_top()->external_caught_exception_ = false;
1269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      clear_pending_exception();
1270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return false;
1271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Reschedule the exception.
1275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->scheduled_exception_ = pending_exception();
1276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  clear_pending_exception();
1277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return true;
1278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Isolate::SetCaptureStackTraceForUncaughtExceptions(
1282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      bool capture,
1283257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      int frame_limit,
1284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StackTrace::StackTraceOptions options) {
1285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  capture_stack_trace_for_uncaught_exceptions_ = capture;
1286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
1287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  stack_trace_for_uncaught_exceptions_options_ = options;
1288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool Isolate::is_out_of_memory() {
1292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (has_pending_exception()) {
1293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    MaybeObject* e = pending_exception();
1294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return true;
1296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (has_scheduled_exception()) {
1299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    MaybeObject* e = scheduled_exception();
1300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return true;
1302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return false;
1305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Context> Isolate::global_context() {
1309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  GlobalObject* global = thread_local_top()->context_->global();
1310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Handle<Context>(global->global_context());
1311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Context> Isolate::GetCallingGlobalContext() {
1315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JavaScriptFrameIterator it;
1316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
1317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (debug_->InDebugger()) {
1318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    while (!it.done()) {
1319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      JavaScriptFrame* frame = it.frame();
1320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Context* context = Context::cast(frame->context());
1321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (context->global_context() == *debug_->debug_context()) {
1322257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        it.Advance();
1323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      } else {
1324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        break;
1325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
1326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif  // ENABLE_DEBUGGER_SUPPORT
1329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (it.done()) return Handle<Context>::null();
1330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JavaScriptFrame* frame = it.frame();
1331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Context* context = Context::cast(frame->context());
1332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Handle<Context>(context->global_context());
1333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochchar* Isolate::ArchiveThread(char* to) {
1337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
1338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    RuntimeProfiler::IsolateExitedJS(this);
1339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  memcpy(to, reinterpret_cast<char*>(thread_local_top()),
1341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         sizeof(ThreadLocalTop));
1342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  InitializeThreadLocal();
13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  clear_pending_exception();
13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  clear_pending_message();
13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  clear_scheduled_exception();
1346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return to + sizeof(ThreadLocalTop);
1347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1348257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1349257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1350257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochchar* Isolate::RestoreThread(char* from) {
1351257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  memcpy(reinterpret_cast<char*>(thread_local_top()), from,
1352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         sizeof(ThreadLocalTop));
1353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // This might be just paranoia, but it seems to be needed in case a
1354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // thread_local_top_ is restored on a separate OS thread.
1355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef USE_SIMULATOR
1356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef V8_TARGET_ARCH_ARM
1357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->simulator_ = Simulator::current(this);
1358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#elif V8_TARGET_ARCH_MIPS
1359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top()->simulator_ = Simulator::current(this);
1360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
1361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
1362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
1363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    RuntimeProfiler::IsolateEnteredJS(this);
1364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
13653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ASSERT(context() == NULL || context()->IsContext());
1366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return from + sizeof(ThreadLocalTop);
1367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
137044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate::ThreadDataTable::ThreadDataTable()
137144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : list_(NULL) {
137244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
137344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
137444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
137544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate::PerIsolateThreadData*
13768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    Isolate::ThreadDataTable::Lookup(Isolate* isolate,
13778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                     ThreadId thread_id) {
137844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
137944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (data->Matches(isolate, thread_id)) return data;
138044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
138144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return NULL;
138244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
138344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
138444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
138544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
138644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (list_ != NULL) list_->prev_ = data;
138744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  data->next_ = list_;
138844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  list_ = data;
138944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
139044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
139344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (list_ == data) list_ = data->next_;
139444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (data->next_ != NULL) data->next_->prev_ = data->prev_;
139544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (data->prev_ != NULL) data->prev_->next_ = data->next_;
139669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  delete data;
139744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
139844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
139944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Isolate::ThreadDataTable::Remove(Isolate* isolate,
14018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                      ThreadId thread_id) {
140244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* data = Lookup(isolate, thread_id);
140344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (data != NULL) {
140444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Remove(data);
140544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
140644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
140744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
140844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
14103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PerIsolateThreadData* data = list_;
14113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  while (data != NULL) {
14123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    PerIsolateThreadData* next = data->next_;
14133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (data->isolate() == isolate) Remove(data);
14143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    data = next;
14153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
14163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
14173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
141944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
142044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define TRACE_ISOLATE(tag)                                              \
142144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  do {                                                                  \
142244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (FLAG_trace_isolates) {                                          \
142344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      PrintF("Isolate %p " #tag "\n", reinterpret_cast<void*>(this));   \
142444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }                                                                   \
142544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } while (false)
142644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else
142744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define TRACE_ISOLATE(tag)
142844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
142944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
143044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
143144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate::Isolate()
143244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : state_(UNINITIALIZED),
143344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      entry_stack_(NULL),
143444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      stack_trace_nesting_level_(0),
143544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      incomplete_message_(NULL),
143644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      preallocated_memory_thread_(NULL),
143744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      preallocated_message_space_(NULL),
143844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      bootstrapper_(NULL),
143944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      runtime_profiler_(NULL),
144044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      compilation_cache_(NULL),
144169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      counters_(NULL),
144244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      code_range_(NULL),
144369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      // Must be initialized early to allow v8::SetResourceConstraints calls.
144444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break_access_(OS::CreateMutex()),
144569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      debugger_initialized_(false),
144669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      // Must be initialized early to allow v8::Debug calls.
144769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      debugger_access_(OS::CreateMutex()),
144869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      logger_(NULL),
144969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      stats_table_(NULL),
145044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      stub_cache_(NULL),
145144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      deoptimizer_data_(NULL),
145244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      capture_stack_trace_for_uncaught_exceptions_(false),
145344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      stack_trace_for_uncaught_exceptions_frame_limit_(0),
145444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
145544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      transcendental_cache_(NULL),
145644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      memory_allocator_(NULL),
145744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      keyed_lookup_cache_(NULL),
145844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      context_slot_cache_(NULL),
145944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      descriptor_lookup_cache_(NULL),
146044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      handle_scope_implementer_(NULL),
14618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      unicode_cache_(NULL),
146244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      in_use_list_(0),
146344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      free_list_(0),
146444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      preallocated_storage_preallocated_(false),
14653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      inner_pointer_to_code_cache_(NULL),
146644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      write_input_buffer_(NULL),
146744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      global_handles_(NULL),
146844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      context_switcher_(NULL),
146944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      thread_manager_(NULL),
14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      fp_stubs_generated_(false),
14713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      has_installed_extensions_(false),
147244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      string_tracker_(NULL),
147344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      regexp_stack_(NULL),
14743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      date_cache_(NULL),
14753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      embedder_data_(NULL),
14763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      context_exit_happened_(false) {
147744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  TRACE_ISOLATE(constructor);
147844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
147944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(isolate_addresses_, 0,
1480589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
148144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
148244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  heap_.isolate_ = this;
148344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  zone_.isolate_ = this;
148444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  stack_guard_.isolate_ = this;
148544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // ThreadManager is initialized early to support locking an isolate
1487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // before it is entered.
1488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_manager_ = new ThreadManager();
1489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_manager_->isolate_ = this;
1490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
149144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
149244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
149344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  simulator_initialized_ = false;
149444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  simulator_i_cache_ = NULL;
149544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  simulator_redirection_ = NULL;
149644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
149744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
149844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
149944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // heap_histograms_ initializes itself.
150044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(&js_spill_information_, 0, sizeof(js_spill_information_));
150144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(code_kind_statistics_, 0,
150244f0eee88ff00398ff7f715fab053374d808c90dSteve Block         sizeof(code_kind_statistics_[0]) * Code::NUMBER_OF_KINDS);
150344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
150444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
150544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
150644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  debug_ = NULL;
150744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  debugger_ = NULL;
150844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
150944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
151044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  handle_scope_data_.Initialize();
151144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
151244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
151344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  name##_ = (initial_value);
151444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_LIST(ISOLATE_INIT_EXECUTE)
151544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef ISOLATE_INIT_EXECUTE
151644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
151744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)                         \
151844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(name##_, 0, sizeof(type) * length);
151944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
152044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef ISOLATE_INIT_ARRAY_EXECUTE
152144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
152244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
152344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::TearDown() {
152444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  TRACE_ISOLATE(tear_down);
152544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
152644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Temporarily set this isolate as current so that various parts of
152744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the isolate can access it in their destructors without having a
152844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // direct pointer. We don't use Enter/Exit here to avoid
152944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // initializing the thread data.
153044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
153144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* saved_isolate = UncheckedCurrent();
153244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SetIsolateThreadLocals(this, NULL);
153344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
153444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Deinit();
153544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
153685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  { ScopedLock lock(process_wide_mutex_);
153785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    thread_data_table_->RemoveAllThreads(this);
15383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
15393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
154044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsDefaultIsolate()) {
154144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    delete this;
154244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
154344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Restore the previous current isolate.
154544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SetIsolateThreadLocals(saved_isolate, saved_data);
154644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
154744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::Deinit() {
155044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (state_ == INITIALIZED) {
155144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    TRACE_ISOLATE(deinit);
155244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
155344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (FLAG_hydrogen_stats) HStatistics::Instance()->Print();
155444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
155544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // We must stop the logger before we tear down other components.
155644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    logger_->EnsureTickerStopped();
155744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
155844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    delete deoptimizer_data_;
155944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    deoptimizer_data_ = NULL;
156044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (FLAG_preemption) {
156144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      v8::Locker locker;
156244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      v8::Locker::StopPreemption();
156344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
156444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    builtins_.TearDown();
156544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    bootstrapper_->TearDown();
156644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
156744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Remove the external reference to the preallocated stack memory.
156844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    delete preallocated_message_space_;
156944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    preallocated_message_space_ = NULL;
157044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PreallocatedMemoryThreadStop();
157144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
157244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    HeapProfiler::TearDown();
157344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuProfiler::TearDown();
157444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (runtime_profiler_ != NULL) {
157544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      runtime_profiler_->TearDown();
157644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      delete runtime_profiler_;
157744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      runtime_profiler_ = NULL;
157844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
157944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    heap_.TearDown();
158044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    logger_->TearDown();
158144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
158244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // The default isolate is re-initializable due to legacy API.
158369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    state_ = UNINITIALIZED;
158444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
158544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
158644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
158744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
158844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::SetIsolateThreadLocals(Isolate* isolate,
158944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                     PerIsolateThreadData* data) {
159085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Thread::SetThreadLocal(isolate_key_, isolate);
159185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
159244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
159344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockIsolate::~Isolate() {
159644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  TRACE_ISOLATE(destructor);
159744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Has to be called while counters_ are still alive.
159969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  zone_.DeleteKeptSegment();
160069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
160169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  delete[] assembler_spare_buffer_;
160269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  assembler_spare_buffer_ = NULL;
160369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
16048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  delete unicode_cache_;
16058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  unicode_cache_ = NULL;
160644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
16073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  delete date_cache_;
16083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  date_cache_ = NULL;
16093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
161044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete regexp_stack_;
161144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  regexp_stack_ = NULL;
161244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
161344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete descriptor_lookup_cache_;
161444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  descriptor_lookup_cache_ = NULL;
161544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete context_slot_cache_;
161644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  context_slot_cache_ = NULL;
161744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete keyed_lookup_cache_;
161844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  keyed_lookup_cache_ = NULL;
161944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
162044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete transcendental_cache_;
162144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  transcendental_cache_ = NULL;
162244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete stub_cache_;
162344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  stub_cache_ = NULL;
162444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete stats_table_;
162544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  stats_table_ = NULL;
162644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
162744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete logger_;
162844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  logger_ = NULL;
162944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
163044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete counters_;
163144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  counters_ = NULL;
163244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
163344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete handle_scope_implementer_;
163444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  handle_scope_implementer_ = NULL;
163544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete break_access_;
163644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  break_access_ = NULL;
163769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  delete debugger_access_;
163869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  debugger_access_ = NULL;
163944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
164044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete compilation_cache_;
164144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  compilation_cache_ = NULL;
164244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete bootstrapper_;
164344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bootstrapper_ = NULL;
16443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  delete inner_pointer_to_code_cache_;
16453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inner_pointer_to_code_cache_ = NULL;
164644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete write_input_buffer_;
164744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  write_input_buffer_ = NULL;
164844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
164944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete context_switcher_;
165044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  context_switcher_ = NULL;
165144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete thread_manager_;
165244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  thread_manager_ = NULL;
165344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
165444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete string_tracker_;
165544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  string_tracker_ = NULL;
165644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
165744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete memory_allocator_;
165844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memory_allocator_ = NULL;
165944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete code_range_;
166044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  code_range_ = NULL;
166144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete global_handles_;
166244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  global_handles_ = NULL;
166344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
166469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  delete external_reference_table_;
166569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  external_reference_table_ = NULL;
166669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
166744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
166844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete debugger_;
166944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  debugger_ = NULL;
167044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete debug_;
167144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  debug_ = NULL;
167244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
167344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
167444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
167544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
167644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::InitializeThreadLocal() {
1677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread_local_top_.isolate_ = this;
167844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  thread_local_top_.Initialize();
167944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
168044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
168144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
16828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid Isolate::PropagatePendingExceptionToExternalTryCatch() {
16838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ASSERT(has_pending_exception());
16848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
16858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  bool external_caught = IsExternallyCaught();
16868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  thread_local_top_.external_caught_exception_ = external_caught;
16878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
16888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (!external_caught) return;
16898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
16908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
16918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // Do not propagate OOM exception: we should kill VM asap.
16928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } else if (thread_local_top_.pending_exception_ ==
16938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch             heap()->termination_exception()) {
16948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    try_catch_handler()->can_continue_ = false;
16958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    try_catch_handler()->exception_ = heap()->null_value();
16968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } else {
16978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // At this point all non-object (failure) exceptions have
16988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    // been dealt with so this shouldn't fail.
16998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ASSERT(!pending_exception()->IsFailure());
17008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    try_catch_handler()->can_continue_ = true;
17018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    try_catch_handler()->exception_ = pending_exception();
17028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
17038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      try_catch_handler()->message_ = thread_local_top_.pending_message_obj_;
17048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
17058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
17068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
17078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
17088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
170969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid Isolate::InitializeLoggingAndCounters() {
171069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (logger_ == NULL) {
171169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    logger_ = new Logger;
171269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
171369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (counters_ == NULL) {
171469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    counters_ = new Counters;
171569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
171669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
171769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
171869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
171969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid Isolate::InitializeDebugger() {
172069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
172169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  ScopedLock lock(debugger_access_);
172269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (NoBarrier_Load(&debugger_initialized_)) return;
172369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  InitializeLoggingAndCounters();
172469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  debug_ = new Debug(this);
172569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  debugger_ = new Debugger(this);
172669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Release_Store(&debugger_initialized_, true);
172769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
172869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
172969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
173069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
173144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool Isolate::Init(Deserializer* des) {
173244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(state_ != INITIALIZED);
173369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  ASSERT(Isolate::Current() == this);
173444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  TRACE_ISOLATE(init);
173544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
173644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
173744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The initialization process does not handle memory exhaustion.
173844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DisallowAllocationFailure disallow_allocation_failure;
173944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
174044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
174169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  InitializeLoggingAndCounters();
174269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
174369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  InitializeDebugger();
174469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
174569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  memory_allocator_ = new MemoryAllocator(this);
174669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  code_range_ = new CodeRange(this);
174769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
174869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Safe after setting Heap::isolate_, initializing StackGuard and
174969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // ensuring that Isolate::Current() == this.
175069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  heap_.SetStackLimits();
175169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1752589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define ASSIGN_ELEMENT(CamelName, hacker_name)                  \
1753589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  isolate_addresses_[Isolate::k##CamelName##Address] =          \
1754589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      reinterpret_cast<Address>(hacker_name##_address());
1755589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT)
175669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#undef C
175769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
175869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  string_tracker_ = new StringTracker();
175969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  string_tracker_->isolate_ = this;
176069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  compilation_cache_ = new CompilationCache(this);
176169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  transcendental_cache_ = new TranscendentalCache();
176269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  keyed_lookup_cache_ = new KeyedLookupCache();
176369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  context_slot_cache_ = new ContextSlotCache();
176469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  descriptor_lookup_cache_ = new DescriptorLookupCache();
176569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  unicode_cache_ = new UnicodeCache();
17663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
176769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  write_input_buffer_ = new StringInputBuffer();
176869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  global_handles_ = new GlobalHandles(this);
176969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bootstrapper_ = new Bootstrapper();
177069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  handle_scope_implementer_ = new HandleScopeImplementer(this);
177169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  stub_cache_ = new StubCache(this);
177269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  regexp_stack_ = new RegExpStack();
177369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  regexp_stack_->isolate_ = this;
17743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  date_cache_ = new DateCache();
177544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
177644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Enable logging before setting up the heap
17773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  logger_->SetUp();
177844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
17793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CpuProfiler::SetUp();
17803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HeapProfiler::SetUp();
178144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
178244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Initialize other runtime facilities
178344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#if defined(USE_SIMULATOR)
178444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
1785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Simulator::Initialize(this);
178644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
178744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
178844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
178944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { // NOLINT
179044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Ensure that the thread has a valid stack guard.  The v8::Locker object
179144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // will ensure this too, but we don't have to use lockers if we are only
179244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // using one thread.
179344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExecutionAccess lock(this);
179444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    stack_guard_.InitThread(lock);
179544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
179644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
17973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // SetUp the object heap.
179869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  const bool create_heap_objects = (des == NULL);
17993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!heap_.HasBeenSetUp());
18003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!heap_.SetUp(create_heap_objects)) {
180144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    V8::SetFatalError();
180244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return false;
180344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
180444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
18053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  InitializeThreadLocal();
18063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
180744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bootstrapper_->Initialize(create_heap_objects);
18083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  builtins_.SetUp(create_heap_objects);
180944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
181044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Only preallocate on the first initialization.
181144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
181244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Start the thread which will set aside some memory.
181344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PreallocatedMemoryThreadStart();
181444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    preallocated_message_space_ =
181544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        new NoAllocationStringAllocator(
181644f0eee88ff00398ff7f715fab053374d808c90dSteve Block            preallocated_memory_thread_->data(),
181744f0eee88ff00398ff7f715fab053374d808c90dSteve Block            preallocated_memory_thread_->length());
181844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    PreallocatedStorageInit(preallocated_memory_thread_->length() / 4);
181944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
182044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
182144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (FLAG_preemption) {
182244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    v8::Locker locker;
182344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    v8::Locker::StartPreemption(100);
182444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
182544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
182644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
18273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  debug_->SetUp(create_heap_objects);
182844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
182944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
183044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // If we are deserializing, read the state into the now-empty heap.
183144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (des != NULL) {
183244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    des->Deserialize();
183344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
18343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  stub_cache_->Initialize();
18353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
18363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Finish initialization of ThreadLocal after deserialization is done.
18373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  clear_pending_exception();
18383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  clear_pending_message();
18393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  clear_scheduled_exception();
1840592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
184144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Deserializing may put strange things in the root array's copy of the
184244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // stack guard.
184344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  heap_.SetStackLimits();
184444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1845db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch  // Quiet the heap NaN if needed on target platform.
1846db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch  if (des != NULL) Assembler::QuietNaN(heap_.nan_value());
1847db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch
184844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  deoptimizer_data_ = new DeoptimizerData;
184944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  runtime_profiler_ = new RuntimeProfiler(this);
18503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  runtime_profiler_->SetUp();
185144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
185244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // If we are deserializing, log non-function code objects and compiled
185344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // functions found in the snapshot.
1854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (des != NULL && (FLAG_log_code || FLAG_ll_prof)) {
185544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    HandleScope scope;
185644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(this, LogCodeObjects());
185744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(this, LogCompiledFunctions());
185844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
185944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
186044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  state_ = INITIALIZED;
18613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  time_millis_at_init_ = OS::TimeCurrentMillis();
186244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return true;
186344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
186444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
186544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
186669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Initialized lazily to allow early
186769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// v8::V8::SetAddHistogramSampleFunction calls.
186869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochStatsTable* Isolate::stats_table() {
186969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (stats_table_ == NULL) {
187069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    stats_table_ = new StatsTable;
187169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
187269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return stats_table_;
187369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
187469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
187569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
187644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::Enter() {
187744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* current_isolate = NULL;
187844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
187944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (current_data != NULL) {
188044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    current_isolate = current_data->isolate_;
188144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(current_isolate != NULL);
188244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (current_isolate == this) {
188344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ASSERT(Current() == this);
188444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ASSERT(entry_stack_ != NULL);
188544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ASSERT(entry_stack_->previous_thread_data == NULL ||
18868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch             entry_stack_->previous_thread_data->thread_id().Equals(
18878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                 ThreadId::Current()));
188844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      // Same thread re-enters the isolate, no need to re-init anything.
188944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      entry_stack_->entry_count++;
189044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return;
189144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
189244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
189344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
189444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Threads can have default isolate set into TLS as Current but not yet have
189544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // PerIsolateThreadData for it, as it requires more advanced phase of the
189644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // initialization. For example, a thread might be the one that system used for
189744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // static initializers - in this case the default isolate is set in TLS but
189844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the thread did not yet Enter the isolate. If PerisolateThreadData is not
189944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // there, use the isolate set in TLS.
190044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (current_isolate == NULL) {
190144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    current_isolate = Isolate::UncheckedCurrent();
190244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
190344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
190444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
190544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(data != NULL);
190644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(data->isolate_ == this);
190744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
190844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EntryStackItem* item = new EntryStackItem(current_data,
190944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                            current_isolate,
191044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                            entry_stack_);
191144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  entry_stack_ = item;
191244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
191344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SetIsolateThreadLocals(this, data);
191444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
191544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // In case it's the first time some thread enters the isolate.
191644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  set_thread_id(data->thread_id());
191744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
191844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
191944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
192044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Isolate::Exit() {
192144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(entry_stack_ != NULL);
192244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(entry_stack_->previous_thread_data == NULL ||
19238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch         entry_stack_->previous_thread_data->thread_id().Equals(
19248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch             ThreadId::Current()));
192544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
192644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (--entry_stack_->entry_count > 0) return;
192744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
192844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(CurrentPerIsolateThreadData() != NULL);
192944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(CurrentPerIsolateThreadData()->isolate_ == this);
193044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
193144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Pop the stack.
193244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EntryStackItem* item = entry_stack_;
193344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  entry_stack_ = item->previous_item;
193444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
193544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
193644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* previous_isolate = item->previous_isolate;
193744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
193844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  delete item;
193944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
194044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Reinit the current thread for the isolate it was running before this one.
194144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SetIsolateThreadLocals(previous_isolate, previous_thread_data);
194244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
194344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
194444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
194544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
194644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
194744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
194844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
194944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
195044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef ISOLATE_FIELD_OFFSET
195144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
195244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
195344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} }  // namespace v8::internal
1954