Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <stdlib.h>
     29 
     30 #include "v8.h"
     31 
     32 #include "ast.h"
     33 #include "bootstrapper.h"
     34 #include "codegen.h"
     35 #include "compilation-cache.h"
     36 #include "debug.h"
     37 #include "deoptimizer.h"
     38 #include "heap-profiler.h"
     39 #include "hydrogen.h"
     40 #include "isolate.h"
     41 #include "lithium-allocator.h"
     42 #include "log.h"
     43 #include "regexp-stack.h"
     44 #include "runtime-profiler.h"
     45 #include "scanner.h"
     46 #include "scopeinfo.h"
     47 #include "serialize.h"
     48 #include "simulator.h"
     49 #include "spaces.h"
     50 #include "stub-cache.h"
     51 #include "version.h"
     52 
     53 
     54 namespace v8 {
     55 namespace internal {
     56 
     57 Atomic32 ThreadId::highest_thread_id_ = 0;
     58 
     59 int ThreadId::AllocateThreadId() {
     60   int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
     61   return new_id;
     62 }
     63 
     64 int ThreadId::GetCurrentThreadId() {
     65   int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
     66   if (thread_id == 0) {
     67     thread_id = AllocateThreadId();
     68     Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
     69   }
     70   return thread_id;
     71 }
     72 
     73 
     74 // Create a dummy thread that will wait forever on a semaphore. The only
     75 // purpose for this thread is to have some stack area to save essential data
     76 // into for use by a stacks only core dump (aka minidump).
     77 class PreallocatedMemoryThread: public Thread {
     78  public:
     79   char* data() {
     80     if (data_ready_semaphore_ != NULL) {
     81       // Initial access is guarded until the data has been published.
     82       data_ready_semaphore_->Wait();
     83       delete data_ready_semaphore_;
     84       data_ready_semaphore_ = NULL;
     85     }
     86     return data_;
     87   }
     88 
     89   unsigned length() {
     90     if (data_ready_semaphore_ != NULL) {
     91       // Initial access is guarded until the data has been published.
     92       data_ready_semaphore_->Wait();
     93       delete data_ready_semaphore_;
     94       data_ready_semaphore_ = NULL;
     95     }
     96     return length_;
     97   }
     98 
     99   // Stop the PreallocatedMemoryThread and release its resources.
    100   void StopThread() {
    101     keep_running_ = false;
    102     wait_for_ever_semaphore_->Signal();
    103 
    104     // Wait for the thread to terminate.
    105     Join();
    106 
    107     if (data_ready_semaphore_ != NULL) {
    108       delete data_ready_semaphore_;
    109       data_ready_semaphore_ = NULL;
    110     }
    111 
    112     delete wait_for_ever_semaphore_;
    113     wait_for_ever_semaphore_ = NULL;
    114   }
    115 
    116  protected:
    117   // When the thread starts running it will allocate a fixed number of bytes
    118   // on the stack and publish the location of this memory for others to use.
    119   void Run() {
    120     EmbeddedVector<char, 15 * 1024> local_buffer;
    121 
    122     // Initialize the buffer with a known good value.
    123     OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
    124                 local_buffer.length());
    125 
    126     // Publish the local buffer and signal its availability.
    127     data_ = local_buffer.start();
    128     length_ = local_buffer.length();
    129     data_ready_semaphore_->Signal();
    130 
    131     while (keep_running_) {
    132       // This thread will wait here until the end of time.
    133       wait_for_ever_semaphore_->Wait();
    134     }
    135 
    136     // Make sure we access the buffer after the wait to remove all possibility
    137     // of it being optimized away.
    138     OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
    139                 local_buffer.length());
    140   }
    141 
    142 
    143  private:
    144   explicit PreallocatedMemoryThread(Isolate* isolate)
    145       : Thread(isolate, "v8:PreallocMem"),
    146         keep_running_(true),
    147         wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
    148         data_ready_semaphore_(OS::CreateSemaphore(0)),
    149         data_(NULL),
    150         length_(0) {
    151   }
    152 
    153   // Used to make sure that the thread keeps looping even for spurious wakeups.
    154   bool keep_running_;
    155 
    156   // This semaphore is used by the PreallocatedMemoryThread to wait for ever.
    157   Semaphore* wait_for_ever_semaphore_;
    158   // Semaphore to signal that the data has been initialized.
    159   Semaphore* data_ready_semaphore_;
    160 
    161   // Location and size of the preallocated memory block.
    162   char* data_;
    163   unsigned length_;
    164 
    165   friend class Isolate;
    166 
    167   DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread);
    168 };
    169 
    170 
    171 void Isolate::PreallocatedMemoryThreadStart() {
    172   if (preallocated_memory_thread_ != NULL) return;
    173   preallocated_memory_thread_ = new PreallocatedMemoryThread(this);
    174   preallocated_memory_thread_->Start();
    175 }
    176 
    177 
    178 void Isolate::PreallocatedMemoryThreadStop() {
    179   if (preallocated_memory_thread_ == NULL) return;
    180   preallocated_memory_thread_->StopThread();
    181   // Done with the thread entirely.
    182   delete preallocated_memory_thread_;
    183   preallocated_memory_thread_ = NULL;
    184 }
    185 
    186 
    187 void Isolate::PreallocatedStorageInit(size_t size) {
    188   ASSERT(free_list_.next_ == &free_list_);
    189   ASSERT(free_list_.previous_ == &free_list_);
    190   PreallocatedStorage* free_chunk =
    191       reinterpret_cast<PreallocatedStorage*>(new char[size]);
    192   free_list_.next_ = free_list_.previous_ = free_chunk;
    193   free_chunk->next_ = free_chunk->previous_ = &free_list_;
    194   free_chunk->size_ = size - sizeof(PreallocatedStorage);
    195   preallocated_storage_preallocated_ = true;
    196 }
    197 
    198 
    199 void* Isolate::PreallocatedStorageNew(size_t size) {
    200   if (!preallocated_storage_preallocated_) {
    201     return FreeStoreAllocationPolicy::New(size);
    202   }
    203   ASSERT(free_list_.next_ != &free_list_);
    204   ASSERT(free_list_.previous_ != &free_list_);
    205 
    206   size = (size + kPointerSize - 1) & ~(kPointerSize - 1);
    207   // Search for exact fit.
    208   for (PreallocatedStorage* storage = free_list_.next_;
    209        storage != &free_list_;
    210        storage = storage->next_) {
    211     if (storage->size_ == size) {
    212       storage->Unlink();
    213       storage->LinkTo(&in_use_list_);
    214       return reinterpret_cast<void*>(storage + 1);
    215     }
    216   }
    217   // Search for first fit.
    218   for (PreallocatedStorage* storage = free_list_.next_;
    219        storage != &free_list_;
    220        storage = storage->next_) {
    221     if (storage->size_ >= size + sizeof(PreallocatedStorage)) {
    222       storage->Unlink();
    223       storage->LinkTo(&in_use_list_);
    224       PreallocatedStorage* left_over =
    225           reinterpret_cast<PreallocatedStorage*>(
    226               reinterpret_cast<char*>(storage + 1) + size);
    227       left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage);
    228       ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) ==
    229              storage->size_);
    230       storage->size_ = size;
    231       left_over->LinkTo(&free_list_);
    232       return reinterpret_cast<void*>(storage + 1);
    233     }
    234   }
    235   // Allocation failure.
    236   ASSERT(false);
    237   return NULL;
    238 }
    239 
    240 
    241 // We don't attempt to coalesce.
    242 void Isolate::PreallocatedStorageDelete(void* p) {
    243   if (p == NULL) {
    244     return;
    245   }
    246   if (!preallocated_storage_preallocated_) {
    247     FreeStoreAllocationPolicy::Delete(p);
    248     return;
    249   }
    250   PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1;
    251   ASSERT(storage->next_->previous_ == storage);
    252   ASSERT(storage->previous_->next_ == storage);
    253   storage->Unlink();
    254   storage->LinkTo(&free_list_);
    255 }
    256 
    257 
    258 Isolate* Isolate::default_isolate_ = NULL;
    259 Thread::LocalStorageKey Isolate::isolate_key_;
    260 Thread::LocalStorageKey Isolate::thread_id_key_;
    261 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
    262 Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
    263 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
    264 
    265 
    266 class IsolateInitializer {
    267  public:
    268   IsolateInitializer() {
    269     Isolate::EnsureDefaultIsolate();
    270   }
    271 };
    272 
    273 static IsolateInitializer* EnsureDefaultIsolateAllocated() {
    274   // TODO(isolates): Use the system threading API to do this once?
    275   static IsolateInitializer static_initializer;
    276   return &static_initializer;
    277 }
    278 
    279 // This variable only needed to trigger static intialization.
    280 static IsolateInitializer* static_initializer = EnsureDefaultIsolateAllocated();
    281 
    282 
    283 
    284 
    285 
    286 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
    287     ThreadId thread_id) {
    288   ASSERT(!thread_id.Equals(ThreadId::Invalid()));
    289   PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
    290   {
    291     ScopedLock lock(process_wide_mutex_);
    292     ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL);
    293     thread_data_table_->Insert(per_thread);
    294     ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
    295   }
    296   return per_thread;
    297 }
    298 
    299 
    300 Isolate::PerIsolateThreadData*
    301     Isolate::FindOrAllocatePerThreadDataForThisThread() {
    302   ThreadId thread_id = ThreadId::Current();
    303   PerIsolateThreadData* per_thread = NULL;
    304   {
    305     ScopedLock lock(process_wide_mutex_);
    306     per_thread = thread_data_table_->Lookup(this, thread_id);
    307     if (per_thread == NULL) {
    308       per_thread = AllocatePerIsolateThreadData(thread_id);
    309     }
    310   }
    311   return per_thread;
    312 }
    313 
    314 
    315 void Isolate::EnsureDefaultIsolate() {
    316   ScopedLock lock(process_wide_mutex_);
    317   if (default_isolate_ == NULL) {
    318     isolate_key_ = Thread::CreateThreadLocalKey();
    319     thread_id_key_ = Thread::CreateThreadLocalKey();
    320     per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
    321     thread_data_table_ = new Isolate::ThreadDataTable();
    322     default_isolate_ = new Isolate();
    323   }
    324   // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
    325   // becase a non-null thread data may be already set.
    326   Thread::SetThreadLocal(isolate_key_, default_isolate_);
    327 }
    328 
    329 
    330 Debugger* Isolate::GetDefaultIsolateDebugger() {
    331   EnsureDefaultIsolate();
    332   return default_isolate_->debugger();
    333 }
    334 
    335 
    336 StackGuard* Isolate::GetDefaultIsolateStackGuard() {
    337   EnsureDefaultIsolate();
    338   return default_isolate_->stack_guard();
    339 }
    340 
    341 
    342 void Isolate::EnterDefaultIsolate() {
    343   EnsureDefaultIsolate();
    344   ASSERT(default_isolate_ != NULL);
    345 
    346   PerIsolateThreadData* data = CurrentPerIsolateThreadData();
    347   // If not yet in default isolate - enter it.
    348   if (data == NULL || data->isolate() != default_isolate_) {
    349     default_isolate_->Enter();
    350   }
    351 }
    352 
    353 
    354 Isolate* Isolate::GetDefaultIsolateForLocking() {
    355   EnsureDefaultIsolate();
    356   return default_isolate_;
    357 }
    358 
    359 
    360 Isolate::ThreadDataTable::ThreadDataTable()
    361     : list_(NULL) {
    362 }
    363 
    364 
    365 Isolate::PerIsolateThreadData*
    366     Isolate::ThreadDataTable::Lookup(Isolate* isolate,
    367                                      ThreadId thread_id) {
    368   for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
    369     if (data->Matches(isolate, thread_id)) return data;
    370   }
    371   return NULL;
    372 }
    373 
    374 
    375 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
    376   if (list_ != NULL) list_->prev_ = data;
    377   data->next_ = list_;
    378   list_ = data;
    379 }
    380 
    381 
    382 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
    383   if (list_ == data) list_ = data->next_;
    384   if (data->next_ != NULL) data->next_->prev_ = data->prev_;
    385   if (data->prev_ != NULL) data->prev_->next_ = data->next_;
    386 }
    387 
    388 
    389 void Isolate::ThreadDataTable::Remove(Isolate* isolate,
    390                                       ThreadId thread_id) {
    391   PerIsolateThreadData* data = Lookup(isolate, thread_id);
    392   if (data != NULL) {
    393     Remove(data);
    394   }
    395 }
    396 
    397 
    398 #ifdef DEBUG
    399 #define TRACE_ISOLATE(tag)                                              \
    400   do {                                                                  \
    401     if (FLAG_trace_isolates) {                                          \
    402       PrintF("Isolate %p " #tag "\n", reinterpret_cast<void*>(this));   \
    403     }                                                                   \
    404   } while (false)
    405 #else
    406 #define TRACE_ISOLATE(tag)
    407 #endif
    408 
    409 
    410 Isolate::Isolate()
    411     : state_(UNINITIALIZED),
    412       entry_stack_(NULL),
    413       stack_trace_nesting_level_(0),
    414       incomplete_message_(NULL),
    415       preallocated_memory_thread_(NULL),
    416       preallocated_message_space_(NULL),
    417       bootstrapper_(NULL),
    418       runtime_profiler_(NULL),
    419       compilation_cache_(NULL),
    420       counters_(NULL),
    421       code_range_(NULL),
    422       // Must be initialized early to allow v8::SetResourceConstraints calls.
    423       break_access_(OS::CreateMutex()),
    424       debugger_initialized_(false),
    425       // Must be initialized early to allow v8::Debug calls.
    426       debugger_access_(OS::CreateMutex()),
    427       logger_(NULL),
    428       stats_table_(NULL),
    429       stub_cache_(NULL),
    430       deoptimizer_data_(NULL),
    431       capture_stack_trace_for_uncaught_exceptions_(false),
    432       stack_trace_for_uncaught_exceptions_frame_limit_(0),
    433       stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
    434       transcendental_cache_(NULL),
    435       memory_allocator_(NULL),
    436       keyed_lookup_cache_(NULL),
    437       context_slot_cache_(NULL),
    438       descriptor_lookup_cache_(NULL),
    439       handle_scope_implementer_(NULL),
    440       unicode_cache_(NULL),
    441       in_use_list_(0),
    442       free_list_(0),
    443       preallocated_storage_preallocated_(false),
    444       pc_to_code_cache_(NULL),
    445       write_input_buffer_(NULL),
    446       global_handles_(NULL),
    447       context_switcher_(NULL),
    448       thread_manager_(NULL),
    449       ast_sentinels_(NULL),
    450       string_tracker_(NULL),
    451       regexp_stack_(NULL),
    452       frame_element_constant_list_(0),
    453       result_constant_list_(0) {
    454   TRACE_ISOLATE(constructor);
    455 
    456   memset(isolate_addresses_, 0,
    457       sizeof(isolate_addresses_[0]) * (k_isolate_address_count + 1));
    458 
    459   heap_.isolate_ = this;
    460   zone_.isolate_ = this;
    461   stack_guard_.isolate_ = this;
    462 
    463 #if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
    464     defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
    465   simulator_initialized_ = false;
    466   simulator_i_cache_ = NULL;
    467   simulator_redirection_ = NULL;
    468 #endif
    469 
    470   thread_manager_ = new ThreadManager();
    471   thread_manager_->isolate_ = this;
    472 
    473 #ifdef DEBUG
    474   // heap_histograms_ initializes itself.
    475   memset(&js_spill_information_, 0, sizeof(js_spill_information_));
    476   memset(code_kind_statistics_, 0,
    477          sizeof(code_kind_statistics_[0]) * Code::NUMBER_OF_KINDS);
    478 #endif
    479 
    480 #ifdef ENABLE_DEBUGGER_SUPPORT
    481   debug_ = NULL;
    482   debugger_ = NULL;
    483 #endif
    484 
    485 #ifdef ENABLE_LOGGING_AND_PROFILING
    486   producer_heap_profile_ = NULL;
    487 #endif
    488 
    489   handle_scope_data_.Initialize();
    490 
    491 #define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
    492   name##_ = (initial_value);
    493   ISOLATE_INIT_LIST(ISOLATE_INIT_EXECUTE)
    494 #undef ISOLATE_INIT_EXECUTE
    495 
    496 #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)                         \
    497   memset(name##_, 0, sizeof(type) * length);
    498   ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
    499 #undef ISOLATE_INIT_ARRAY_EXECUTE
    500 }
    501 
    502 void Isolate::TearDown() {
    503   TRACE_ISOLATE(tear_down);
    504 
    505   // Temporarily set this isolate as current so that various parts of
    506   // the isolate can access it in their destructors without having a
    507   // direct pointer. We don't use Enter/Exit here to avoid
    508   // initializing the thread data.
    509   PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
    510   Isolate* saved_isolate = UncheckedCurrent();
    511   SetIsolateThreadLocals(this, NULL);
    512 
    513   Deinit();
    514 
    515   if (!IsDefaultIsolate()) {
    516     delete this;
    517   }
    518 
    519   // Restore the previous current isolate.
    520   SetIsolateThreadLocals(saved_isolate, saved_data);
    521 }
    522 
    523 
    524 void Isolate::Deinit() {
    525   if (state_ == INITIALIZED) {
    526     TRACE_ISOLATE(deinit);
    527 
    528     if (FLAG_hydrogen_stats) HStatistics::Instance()->Print();
    529 
    530     // We must stop the logger before we tear down other components.
    531     logger_->EnsureTickerStopped();
    532 
    533     delete deoptimizer_data_;
    534     deoptimizer_data_ = NULL;
    535     if (FLAG_preemption) {
    536       v8::Locker locker;
    537       v8::Locker::StopPreemption();
    538     }
    539     builtins_.TearDown();
    540     bootstrapper_->TearDown();
    541 
    542     // Remove the external reference to the preallocated stack memory.
    543     delete preallocated_message_space_;
    544     preallocated_message_space_ = NULL;
    545     PreallocatedMemoryThreadStop();
    546 
    547     HeapProfiler::TearDown();
    548     CpuProfiler::TearDown();
    549     if (runtime_profiler_ != NULL) {
    550       runtime_profiler_->TearDown();
    551       delete runtime_profiler_;
    552       runtime_profiler_ = NULL;
    553     }
    554     heap_.TearDown();
    555     logger_->TearDown();
    556 
    557     // The default isolate is re-initializable due to legacy API.
    558     state_ = UNINITIALIZED;
    559   }
    560 }
    561 
    562 
    563 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
    564                                      PerIsolateThreadData* data) {
    565   Thread::SetThreadLocal(isolate_key_, isolate);
    566   Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
    567 }
    568 
    569 
    570 Isolate::~Isolate() {
    571   TRACE_ISOLATE(destructor);
    572 
    573 #ifdef ENABLE_LOGGING_AND_PROFILING
    574   delete producer_heap_profile_;
    575   producer_heap_profile_ = NULL;
    576 #endif
    577 
    578   delete unicode_cache_;
    579   unicode_cache_ = NULL;
    580 
    581   delete regexp_stack_;
    582   regexp_stack_ = NULL;
    583 
    584   delete ast_sentinels_;
    585   ast_sentinels_ = NULL;
    586 
    587   delete descriptor_lookup_cache_;
    588   descriptor_lookup_cache_ = NULL;
    589   delete context_slot_cache_;
    590   context_slot_cache_ = NULL;
    591   delete keyed_lookup_cache_;
    592   keyed_lookup_cache_ = NULL;
    593 
    594   delete transcendental_cache_;
    595   transcendental_cache_ = NULL;
    596   delete stub_cache_;
    597   stub_cache_ = NULL;
    598   delete stats_table_;
    599   stats_table_ = NULL;
    600 
    601   delete logger_;
    602   logger_ = NULL;
    603 
    604   delete counters_;
    605   counters_ = NULL;
    606 
    607   delete handle_scope_implementer_;
    608   handle_scope_implementer_ = NULL;
    609   delete break_access_;
    610   break_access_ = NULL;
    611 
    612   delete compilation_cache_;
    613   compilation_cache_ = NULL;
    614   delete bootstrapper_;
    615   bootstrapper_ = NULL;
    616   delete pc_to_code_cache_;
    617   pc_to_code_cache_ = NULL;
    618   delete write_input_buffer_;
    619   write_input_buffer_ = NULL;
    620 
    621   delete context_switcher_;
    622   context_switcher_ = NULL;
    623   delete thread_manager_;
    624   thread_manager_ = NULL;
    625 
    626   delete string_tracker_;
    627   string_tracker_ = NULL;
    628 
    629   delete memory_allocator_;
    630   memory_allocator_ = NULL;
    631   delete code_range_;
    632   code_range_ = NULL;
    633   delete global_handles_;
    634   global_handles_ = NULL;
    635 
    636 #ifdef ENABLE_DEBUGGER_SUPPORT
    637   delete debugger_;
    638   debugger_ = NULL;
    639   delete debug_;
    640   debug_ = NULL;
    641 #endif
    642 }
    643 
    644 
    645 void Isolate::InitializeThreadLocal() {
    646   thread_local_top_.Initialize();
    647   clear_pending_exception();
    648   clear_pending_message();
    649   clear_scheduled_exception();
    650 }
    651 
    652 
    653 void Isolate::PropagatePendingExceptionToExternalTryCatch() {
    654   ASSERT(has_pending_exception());
    655 
    656   bool external_caught = IsExternallyCaught();
    657   thread_local_top_.external_caught_exception_ = external_caught;
    658 
    659   if (!external_caught) return;
    660 
    661   if (thread_local_top_.pending_exception_ == Failure::OutOfMemoryException()) {
    662     // Do not propagate OOM exception: we should kill VM asap.
    663   } else if (thread_local_top_.pending_exception_ ==
    664              heap()->termination_exception()) {
    665     try_catch_handler()->can_continue_ = false;
    666     try_catch_handler()->exception_ = heap()->null_value();
    667   } else {
    668     // At this point all non-object (failure) exceptions have
    669     // been dealt with so this shouldn't fail.
    670     ASSERT(!pending_exception()->IsFailure());
    671     try_catch_handler()->can_continue_ = true;
    672     try_catch_handler()->exception_ = pending_exception();
    673     if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
    674       try_catch_handler()->message_ = thread_local_top_.pending_message_obj_;
    675     }
    676   }
    677 }
    678 
    679 
    680 void Isolate::InitializeLoggingAndCounters() {
    681   if (logger_ == NULL) {
    682     logger_ = new Logger;
    683   }
    684   if (counters_ == NULL) {
    685     counters_ = new Counters;
    686   }
    687 }
    688 
    689 
    690 void Isolate::InitializeDebugger() {
    691 #ifdef ENABLE_DEBUGGER_SUPPORT
    692   ScopedLock lock(debugger_access_);
    693   if (NoBarrier_Load(&debugger_initialized_)) return;
    694   InitializeLoggingAndCounters();
    695   debug_ = new Debug(this);
    696   debugger_ = new Debugger(this);
    697   Release_Store(&debugger_initialized_, true);
    698 #endif
    699 }
    700 
    701 
    702 bool Isolate::Init(Deserializer* des) {
    703   ASSERT(state_ != INITIALIZED);
    704   ASSERT(Isolate::Current() == this);
    705   TRACE_ISOLATE(init);
    706 
    707 #ifdef DEBUG
    708   // The initialization process does not handle memory exhaustion.
    709   DisallowAllocationFailure disallow_allocation_failure;
    710 #endif
    711 
    712   InitializeLoggingAndCounters();
    713 
    714   InitializeDebugger();
    715 
    716   memory_allocator_ = new MemoryAllocator(this);
    717   code_range_ = new CodeRange(this);
    718 
    719   // Safe after setting Heap::isolate_, initializing StackGuard and
    720   // ensuring that Isolate::Current() == this.
    721   heap_.SetStackLimits();
    722 
    723 #define C(name) isolate_addresses_[Isolate::k_##name] =                        \
    724     reinterpret_cast<Address>(name());
    725   ISOLATE_ADDRESS_LIST(C)
    726   ISOLATE_ADDRESS_LIST_PROF(C)
    727 #undef C
    728 
    729   string_tracker_ = new StringTracker();
    730   string_tracker_->isolate_ = this;
    731   compilation_cache_ = new CompilationCache(this);
    732   transcendental_cache_ = new TranscendentalCache();
    733   keyed_lookup_cache_ = new KeyedLookupCache();
    734   context_slot_cache_ = new ContextSlotCache();
    735   descriptor_lookup_cache_ = new DescriptorLookupCache();
    736   unicode_cache_ = new UnicodeCache();
    737   pc_to_code_cache_ = new PcToCodeCache(this);
    738   write_input_buffer_ = new StringInputBuffer();
    739   global_handles_ = new GlobalHandles(this);
    740   bootstrapper_ = new Bootstrapper();
    741   handle_scope_implementer_ = new HandleScopeImplementer();
    742   stub_cache_ = new StubCache(this);
    743   ast_sentinels_ = new AstSentinels();
    744   regexp_stack_ = new RegExpStack();
    745   regexp_stack_->isolate_ = this;
    746 
    747 #ifdef ENABLE_LOGGING_AND_PROFILING
    748   producer_heap_profile_ = new ProducerHeapProfile();
    749   producer_heap_profile_->isolate_ = this;
    750 #endif
    751 
    752   // Enable logging before setting up the heap
    753   logger_->Setup();
    754 
    755   CpuProfiler::Setup();
    756   HeapProfiler::Setup();
    757 
    758   // Initialize other runtime facilities
    759 #if defined(USE_SIMULATOR)
    760 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
    761   Simulator::Initialize();
    762 #endif
    763 #endif
    764 
    765   { // NOLINT
    766     // Ensure that the thread has a valid stack guard.  The v8::Locker object
    767     // will ensure this too, but we don't have to use lockers if we are only
    768     // using one thread.
    769     ExecutionAccess lock(this);
    770     stack_guard_.InitThread(lock);
    771   }
    772 
    773   // Setup the object heap.
    774   const bool create_heap_objects = (des == NULL);
    775   ASSERT(!heap_.HasBeenSetup());
    776   if (!heap_.Setup(create_heap_objects)) {
    777     V8::SetFatalError();
    778     return false;
    779   }
    780 
    781   bootstrapper_->Initialize(create_heap_objects);
    782   builtins_.Setup(create_heap_objects);
    783 
    784   InitializeThreadLocal();
    785 
    786   // Only preallocate on the first initialization.
    787   if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
    788     // Start the thread which will set aside some memory.
    789     PreallocatedMemoryThreadStart();
    790     preallocated_message_space_ =
    791         new NoAllocationStringAllocator(
    792             preallocated_memory_thread_->data(),
    793             preallocated_memory_thread_->length());
    794     PreallocatedStorageInit(preallocated_memory_thread_->length() / 4);
    795   }
    796 
    797   if (FLAG_preemption) {
    798     v8::Locker locker;
    799     v8::Locker::StartPreemption(100);
    800   }
    801 
    802 #ifdef ENABLE_DEBUGGER_SUPPORT
    803   debug_->Setup(create_heap_objects);
    804 #endif
    805   stub_cache_->Initialize(create_heap_objects);
    806 
    807   // If we are deserializing, read the state into the now-empty heap.
    808   if (des != NULL) {
    809     des->Deserialize();
    810     stub_cache_->Clear();
    811   }
    812 
    813   // Deserializing may put strange things in the root array's copy of the
    814   // stack guard.
    815   heap_.SetStackLimits();
    816 
    817   deoptimizer_data_ = new DeoptimizerData;
    818   runtime_profiler_ = new RuntimeProfiler(this);
    819   runtime_profiler_->Setup();
    820 
    821   // If we are deserializing, log non-function code objects and compiled
    822   // functions found in the snapshot.
    823   if (des != NULL && FLAG_log_code) {
    824     HandleScope scope;
    825     LOG(this, LogCodeObjects());
    826     LOG(this, LogCompiledFunctions());
    827   }
    828 
    829   state_ = INITIALIZED;
    830   return true;
    831 }
    832 
    833 
    834 // Initialized lazily to allow early
    835 // v8::V8::SetAddHistogramSampleFunction calls.
    836 StatsTable* Isolate::stats_table() {
    837   if (stats_table_ == NULL) {
    838     stats_table_ = new StatsTable;
    839   }
    840   return stats_table_;
    841 }
    842 
    843 
    844 void Isolate::Enter() {
    845   Isolate* current_isolate = NULL;
    846   PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
    847   if (current_data != NULL) {
    848     current_isolate = current_data->isolate_;
    849     ASSERT(current_isolate != NULL);
    850     if (current_isolate == this) {
    851       ASSERT(Current() == this);
    852       ASSERT(entry_stack_ != NULL);
    853       ASSERT(entry_stack_->previous_thread_data == NULL ||
    854              entry_stack_->previous_thread_data->thread_id().Equals(
    855                  ThreadId::Current()));
    856       // Same thread re-enters the isolate, no need to re-init anything.
    857       entry_stack_->entry_count++;
    858       return;
    859     }
    860   }
    861 
    862   // Threads can have default isolate set into TLS as Current but not yet have
    863   // PerIsolateThreadData for it, as it requires more advanced phase of the
    864   // initialization. For example, a thread might be the one that system used for
    865   // static initializers - in this case the default isolate is set in TLS but
    866   // the thread did not yet Enter the isolate. If PerisolateThreadData is not
    867   // there, use the isolate set in TLS.
    868   if (current_isolate == NULL) {
    869     current_isolate = Isolate::UncheckedCurrent();
    870   }
    871 
    872   PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
    873   ASSERT(data != NULL);
    874   ASSERT(data->isolate_ == this);
    875 
    876   EntryStackItem* item = new EntryStackItem(current_data,
    877                                             current_isolate,
    878                                             entry_stack_);
    879   entry_stack_ = item;
    880 
    881   SetIsolateThreadLocals(this, data);
    882 
    883   // In case it's the first time some thread enters the isolate.
    884   set_thread_id(data->thread_id());
    885 }
    886 
    887 
    888 void Isolate::Exit() {
    889   ASSERT(entry_stack_ != NULL);
    890   ASSERT(entry_stack_->previous_thread_data == NULL ||
    891          entry_stack_->previous_thread_data->thread_id().Equals(
    892              ThreadId::Current()));
    893 
    894   if (--entry_stack_->entry_count > 0) return;
    895 
    896   ASSERT(CurrentPerIsolateThreadData() != NULL);
    897   ASSERT(CurrentPerIsolateThreadData()->isolate_ == this);
    898 
    899   // Pop the stack.
    900   EntryStackItem* item = entry_stack_;
    901   entry_stack_ = item->previous_item;
    902 
    903   PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
    904   Isolate* previous_isolate = item->previous_isolate;
    905 
    906   delete item;
    907 
    908   // Reinit the current thread for the isolate it was running before this one.
    909   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
    910 }
    911 
    912 
    913 void Isolate::ResetEagerOptimizingData() {
    914   compilation_cache_->ResetEagerOptimizingData();
    915 }
    916 
    917 
    918 #ifdef DEBUG
    919 #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
    920 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
    921 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
    922 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
    923 #undef ISOLATE_FIELD_OFFSET
    924 #endif
    925 
    926 } }  // namespace v8::internal
    927