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